Merge pull request #373 from greysteil/no-predicate

Add a config option to ignore or raise on unknown predicates & attributes
This commit is contained in:
Jon Atack 2014-05-16 00:06:10 +02:00
commit 0e8ad2a10f
5 changed files with 58 additions and 8 deletions

View File

@ -6,7 +6,10 @@ module Ransack
mattr_accessor :predicates, :options
self.predicates = {}
self.options = { :search_key => :q }
self.options = {
:search_key => :q,
:ignore_unknown_conditions => true
}
def configure
yield self
@ -40,6 +43,11 @@ module Ransack
self.options[:search_key] = name
end
# raise an error if an unknown attribute is passed into a search
def ignore_unknown_conditions=(boolean)
self.options[:ignore_unknown_conditions] = boolean
end
def arel_predicate_with_suffix(arel_predicate, suffix)
if arel_predicate === Proc
proc { |v| "#{arel_predicate.call(v)}#{suffix}" }

View File

@ -10,7 +10,7 @@ module Ransack
class << self
def extract(context, key, values)
attributes, predicate = extract_attributes_and_predicate(key)
if attributes.size > 0
if attributes.size > 0 && predicate
combinator = key.match(/_(or|and)_/) ? $1 : nil
condition = self.new(context)
condition.build(
@ -35,7 +35,9 @@ module Ransack
str = key.dup
name = Predicate.detect_and_strip_from_string!(str)
predicate = Predicate.named(name)
raise ArgumentError, "No valid predicate for #{key}" unless predicate
if predicate.nil? && !Ransack.options[:ignore_unknown_conditions]
raise ArgumentError, "No valid predicate for #{key}"
end
attributes = str.split(/_and_|_or_/)
[attributes, predicate]
end

View File

@ -29,11 +29,12 @@ module Ransack
def build(params)
collapse_multiparameter_attributes!(params).each do |key, value|
case key
when 's', 'sorts'
if ['s', 'sorts'].include?(key)
send("#{key}=", value)
else
base.send("#{key}=", value) if base.attribute_method?(key)
elsif base.attribute_method?(key)
base.send("#{key}=", value)
elsif !Ransack.options[:ignore_unknown_conditions]
raise ArgumentError, "Invalid search term #{key}"
end
end
self

View File

@ -10,6 +10,25 @@ module Ransack
specify { expect(subject.values.size).to eq(2) }
end
context 'with an invalid predicate' do
subject { Condition.extract(Context.for(Person), 'name_invalid', Person.first.name) }
context "when ignore_unknown_conditions is false" do
before do
Ransack.configure { |config| config.ignore_unknown_conditions = false }
end
specify { expect { subject }.to raise_error ArgumentError }
end
context "when ignore_unknown_conditions is true" do
before do
Ransack.configure { |config| config.ignore_unknown_conditions = true }
end
specify { subject.should be_nil }
end
end
end
end
end
end

View File

@ -147,6 +147,26 @@ module Ransack
search = Search.new(Person, :children_id_in => [1, 2, 3])
expect(search.inspect).not_to match /ActiveRecord/
end
context 'with an invalid condition' do
subject { Search.new(Person, :unknown_attr_eq => 'Ernie') }
context "when ignore_unknown_conditions is false" do
before do
Ransack.configure { |config| config.ignore_unknown_conditions = false }
end
specify { expect { subject }.to raise_error ArgumentError }
end
context "when ignore_unknown_conditions is true" do
before do
Ransack.configure { |config| config.ignore_unknown_conditions = true }
end
specify { expect { subject }.to_not raise_error ArgumentError }
end
end
end
describe '#result' do