ransack 1.5.1 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +47 -3
- data/CHANGELOG.md +106 -18
- data/CONTRIBUTING.md +56 -23
- data/Gemfile +16 -5
- data/README.md +114 -38
- data/Rakefile +30 -2
- data/lib/ransack.rb +9 -0
- data/lib/ransack/adapters/active_record/3.0/compat.rb +11 -8
- data/lib/ransack/adapters/active_record/3.0/context.rb +14 -22
- data/lib/ransack/adapters/active_record/3.1/context.rb +14 -22
- data/lib/ransack/adapters/active_record/context.rb +36 -31
- data/lib/ransack/adapters/active_record/ransack/constants.rb +113 -0
- data/lib/ransack/adapters/active_record/ransack/context.rb +64 -0
- data/lib/ransack/adapters/active_record/ransack/nodes/condition.rb +48 -0
- data/lib/ransack/adapters/active_record/ransack/translate.rb +12 -0
- data/lib/ransack/adapters/active_record/ransack/visitor.rb +24 -0
- data/lib/ransack/adapters/mongoid.rb +13 -0
- data/lib/ransack/adapters/mongoid/3.2/.gitkeep +0 -0
- data/lib/ransack/adapters/mongoid/attributes/attribute.rb +37 -0
- data/lib/ransack/adapters/mongoid/attributes/order_predications.rb +17 -0
- data/lib/ransack/adapters/mongoid/attributes/predications.rb +141 -0
- data/lib/ransack/adapters/mongoid/base.rb +126 -0
- data/lib/ransack/adapters/mongoid/context.rb +208 -0
- data/lib/ransack/adapters/mongoid/inquiry_hash.rb +23 -0
- data/lib/ransack/adapters/mongoid/ransack/constants.rb +88 -0
- data/lib/ransack/adapters/mongoid/ransack/context.rb +60 -0
- data/lib/ransack/adapters/mongoid/ransack/nodes/condition.rb +27 -0
- data/lib/ransack/adapters/mongoid/ransack/translate.rb +13 -0
- data/lib/ransack/adapters/mongoid/ransack/visitor.rb +24 -0
- data/lib/ransack/adapters/mongoid/table.rb +35 -0
- data/lib/ransack/configuration.rb +22 -4
- data/lib/ransack/constants.rb +26 -120
- data/lib/ransack/context.rb +32 -60
- data/lib/ransack/helpers/form_builder.rb +50 -36
- data/lib/ransack/helpers/form_helper.rb +148 -104
- data/lib/ransack/naming.rb +11 -11
- data/lib/ransack/nodes.rb +2 -0
- data/lib/ransack/nodes/bindable.rb +12 -4
- data/lib/ransack/nodes/condition.rb +5 -22
- data/lib/ransack/nodes/grouping.rb +9 -10
- data/lib/ransack/nodes/sort.rb +3 -2
- data/lib/ransack/nodes/value.rb +1 -2
- data/lib/ransack/predicate.rb +3 -3
- data/lib/ransack/search.rb +46 -13
- data/lib/ransack/translate.rb +8 -8
- data/lib/ransack/version.rb +1 -1
- data/lib/ransack/visitor.rb +4 -16
- data/ransack.gemspec +1 -0
- data/spec/mongoid/adapters/mongoid/base_spec.rb +276 -0
- data/spec/mongoid/adapters/mongoid/context_spec.rb +56 -0
- data/spec/mongoid/configuration_spec.rb +66 -0
- data/spec/mongoid/dependencies_spec.rb +8 -0
- data/spec/mongoid/helpers/ransack_helper.rb +11 -0
- data/spec/mongoid/nodes/condition_spec.rb +34 -0
- data/spec/mongoid/nodes/grouping_spec.rb +13 -0
- data/spec/mongoid/predicate_spec.rb +155 -0
- data/spec/mongoid/search_spec.rb +446 -0
- data/spec/mongoid/support/mongoid.yml +6 -0
- data/spec/mongoid/support/schema.rb +128 -0
- data/spec/mongoid/translate_spec.rb +14 -0
- data/spec/mongoid_spec_helper.rb +59 -0
- data/spec/ransack/adapters/active_record/base_spec.rb +68 -35
- data/spec/ransack/dependencies_spec.rb +3 -1
- data/spec/ransack/helpers/form_builder_spec.rb +6 -6
- data/spec/ransack/helpers/form_helper_spec.rb +114 -47
- data/spec/ransack/nodes/condition_spec.rb +2 -2
- data/spec/ransack/search_spec.rb +2 -6
- data/spec/ransack/translate_spec.rb +1 -1
- data/spec/spec_helper.rb +2 -3
- data/spec/support/schema.rb +9 -0
- metadata +49 -4
data/lib/ransack/nodes/sort.rb
CHANGED
@@ -8,6 +8,7 @@ module Ransack
|
|
8
8
|
|
9
9
|
class << self
|
10
10
|
def extract(context, str)
|
11
|
+
return unless str
|
11
12
|
attr, direction = str.split(/\s+/,2)
|
12
13
|
self.new(context).build(name: attr, dir: direction)
|
13
14
|
end
|
@@ -37,10 +38,10 @@ module Ransack
|
|
37
38
|
def dir=(dir)
|
38
39
|
dir = dir.downcase if dir
|
39
40
|
@dir =
|
40
|
-
if
|
41
|
+
if Constants::ASC_DESC.include?(dir)
|
41
42
|
dir
|
42
43
|
else
|
43
|
-
|
44
|
+
Constants::ASC
|
44
45
|
end
|
45
46
|
end
|
46
47
|
|
data/lib/ransack/nodes/value.rb
CHANGED
data/lib/ransack/predicate.rb
CHANGED
@@ -19,7 +19,7 @@ module Ransack
|
|
19
19
|
|
20
20
|
def detect_and_strip_from_string!(str)
|
21
21
|
if p = detect_from_string(str)
|
22
|
-
str.sub! /_#{p}$/,
|
22
|
+
str.sub! /_#{p}$/, Constants::EMPTY
|
23
23
|
p
|
24
24
|
end
|
25
25
|
end
|
@@ -49,7 +49,7 @@ module Ransack
|
|
49
49
|
lambda { |v| v.respond_to?(:empty?) ? !v.empty? : !v.nil? }
|
50
50
|
@compound = opts[:compound]
|
51
51
|
@wants_array = opts[:wants_array] == true || @compound ||
|
52
|
-
|
52
|
+
Constants::IN_NOT_IN.include?(@arel_predicate)
|
53
53
|
end
|
54
54
|
|
55
55
|
def eql?(other)
|
@@ -71,7 +71,7 @@ module Ransack
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def validate(vals, type = @type)
|
74
|
-
vals.
|
74
|
+
vals.any? { |v| validator.call(type ? v.cast(type) : v.value) }
|
75
75
|
end
|
76
76
|
|
77
77
|
end
|
data/lib/ransack/search.rb
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
require 'ransack/nodes'
|
2
2
|
require 'ransack/context'
|
3
|
+
|
4
|
+
if defined?(::ActiveRecord::Base)
|
5
|
+
require 'ransack/adapters/active_record/ransack/context'
|
6
|
+
end
|
7
|
+
|
8
|
+
if defined?(::Mongoid)
|
9
|
+
require 'ransack/adapters/mongoid/ransack/context'
|
10
|
+
end
|
11
|
+
|
3
12
|
require 'ransack/naming'
|
4
13
|
|
5
14
|
module Ransack
|
@@ -23,10 +32,10 @@ module Ransack
|
|
23
32
|
@context = options[:context] || Context.for(object, options)
|
24
33
|
@context.auth_object = options[:auth_object]
|
25
34
|
@base = Nodes::Grouping.new(
|
26
|
-
@context,
|
27
|
-
options[:grouping] || Ransack::Constants::AND
|
35
|
+
@context, options[:grouping] || Constants::AND
|
28
36
|
)
|
29
37
|
@scope_args = {}
|
38
|
+
@sorts ||= []
|
30
39
|
build(params.with_indifferent_access)
|
31
40
|
end
|
32
41
|
|
@@ -36,7 +45,7 @@ module Ransack
|
|
36
45
|
|
37
46
|
def build(params)
|
38
47
|
collapse_multiparameter_attributes!(params).each do |key, value|
|
39
|
-
if
|
48
|
+
if Constants::S_SORTS.include?(key)
|
40
49
|
send("#{key}=", value)
|
41
50
|
elsif base.attribute_method?(key)
|
42
51
|
base.send("#{key}=", value)
|
@@ -75,7 +84,7 @@ module Ransack
|
|
75
84
|
alias :s= :sorts=
|
76
85
|
|
77
86
|
def sorts
|
78
|
-
@sorts
|
87
|
+
@sorts
|
79
88
|
end
|
80
89
|
alias :s :sorts
|
81
90
|
|
@@ -91,7 +100,7 @@ module Ransack
|
|
91
100
|
|
92
101
|
def method_missing(method_id, *args)
|
93
102
|
method_name = method_id.to_s
|
94
|
-
getter_name = method_name.sub(/=$/,
|
103
|
+
getter_name = method_name.sub(/=$/, Constants::EMPTY)
|
95
104
|
if base.attribute_method?(getter_name)
|
96
105
|
base.send(method_id, *args)
|
97
106
|
elsif @context.ransackable_scope?(getter_name, @context.object)
|
@@ -111,8 +120,9 @@ module Ransack
|
|
111
120
|
([:scope, @scope_args] if @scope_args.present?),
|
112
121
|
[:base, base.inspect]
|
113
122
|
]
|
114
|
-
.compact
|
115
|
-
.join(
|
123
|
+
.compact
|
124
|
+
.map { |d| d.join(Constants::COLON_SPACE) }
|
125
|
+
.join(Constants::COMMA_SPACE)
|
116
126
|
|
117
127
|
"Ransack::Search<#{details}>"
|
118
128
|
end
|
@@ -123,22 +133,45 @@ module Ransack
|
|
123
133
|
if @context.scope_arity(key) == 1
|
124
134
|
@scope_args[key] = args.is_a?(Array) ? args[0] : args
|
125
135
|
else
|
126
|
-
@scope_args[key] = args
|
136
|
+
@scope_args[key] = args.is_a?(Array) ? sanitized_scope_args(args) : args
|
137
|
+
end
|
138
|
+
@context.chain_scope(key, sanitized_scope_args(args))
|
139
|
+
end
|
140
|
+
|
141
|
+
def sanitized_scope_args(args)
|
142
|
+
if args.is_a?(Array)
|
143
|
+
args = args.map(&method(:sanitized_scope_args))
|
144
|
+
end
|
145
|
+
|
146
|
+
if Constants::TRUE_VALUES.include? args
|
147
|
+
true
|
148
|
+
elsif Constants::FALSE_VALUES.include? args
|
149
|
+
false
|
150
|
+
else
|
151
|
+
args
|
127
152
|
end
|
128
|
-
@context.chain_scope(key, args)
|
129
153
|
end
|
130
154
|
|
131
155
|
def collapse_multiparameter_attributes!(attrs)
|
132
|
-
attrs.
|
133
|
-
if k.include?(
|
156
|
+
attrs.each_key do |k|
|
157
|
+
if k.include?(Constants::LEFT_PARENTHESIS)
|
134
158
|
real_attribute, position = k.split(/\(|\)/)
|
135
|
-
cast =
|
159
|
+
cast =
|
160
|
+
if Constants::A_S_I.include?(position.last)
|
161
|
+
position.last
|
162
|
+
else
|
163
|
+
nil
|
164
|
+
end
|
136
165
|
position = position.to_i - 1
|
137
166
|
value = attrs.delete(k)
|
138
167
|
attrs[real_attribute] ||= []
|
139
168
|
attrs[real_attribute][position] =
|
140
169
|
if cast
|
141
|
-
value.blank? && cast ==
|
170
|
+
if value.blank? && cast == Constants::I
|
171
|
+
nil
|
172
|
+
else
|
173
|
+
value.send("to_#{cast}")
|
174
|
+
end
|
142
175
|
else
|
143
176
|
value
|
144
177
|
end
|
data/lib/ransack/translate.rb
CHANGED
@@ -25,8 +25,7 @@ module Ransack
|
|
25
25
|
|x| x.respond_to?(:model_name)
|
26
26
|
}
|
27
27
|
predicate = Predicate.detect_from_string(original_name)
|
28
|
-
attributes_str = original_name
|
29
|
-
.sub(/_#{predicate}$/, Ransack::Constants::EMPTY)
|
28
|
+
attributes_str = original_name.sub(/_#{predicate}$/, Constants::EMPTY)
|
30
29
|
attribute_names = attributes_str.split(/_and_|_or_/)
|
31
30
|
combinator = attributes_str.match(/_and_/) ? :and : :or
|
32
31
|
defaults = base_ancestors.map do |klass|
|
@@ -74,7 +73,7 @@ module Ransack
|
|
74
73
|
def self.attribute_name(context, name, include_associations = nil)
|
75
74
|
@context, @name = context, name
|
76
75
|
@assoc_path = context.association_path(name)
|
77
|
-
@attr_name = @name.sub(/^#{@assoc_path}_/,
|
76
|
+
@attr_name = @name.sub(/^#{@assoc_path}_/, Constants::EMPTY)
|
78
77
|
associated_class = @context.traverse(@assoc_path) if @assoc_path.present?
|
79
78
|
@include_associated = include_associations && associated_class
|
80
79
|
|
@@ -150,11 +149,12 @@ module Ransack
|
|
150
149
|
end
|
151
150
|
|
152
151
|
def self.i18n_key(klass)
|
153
|
-
if ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR == 0
|
154
|
-
|
155
|
-
else
|
156
|
-
|
157
|
-
end
|
152
|
+
# if ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR == 0
|
153
|
+
# klass.model_name.i18n_key.to_s.tr('.', '/')
|
154
|
+
# else
|
155
|
+
# klass.model_name.i18n_key.to_s
|
156
|
+
# end
|
157
|
+
raise "not implemented"
|
158
158
|
end
|
159
159
|
end
|
160
160
|
end
|
data/lib/ransack/version.rb
CHANGED
data/lib/ransack/visitor.rb
CHANGED
@@ -18,7 +18,7 @@ module Ransack
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def visit_Ransack_Nodes_Grouping(object)
|
21
|
-
if object.combinator ==
|
21
|
+
if object.combinator == Constants::OR
|
22
22
|
visit_or(object)
|
23
23
|
else
|
24
24
|
visit_and(object)
|
@@ -26,14 +26,7 @@ module Ransack
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def visit_and(object)
|
29
|
-
|
30
|
-
return nil unless nodes.size > 0
|
31
|
-
|
32
|
-
if nodes.size > 1
|
33
|
-
Arel::Nodes::Grouping.new(Arel::Nodes::And.new(nodes))
|
34
|
-
else
|
35
|
-
nodes.first
|
36
|
-
end
|
29
|
+
raise "not implemented"
|
37
30
|
end
|
38
31
|
|
39
32
|
def visit_or(object)
|
@@ -52,12 +45,7 @@ module Ransack
|
|
52
45
|
end
|
53
46
|
|
54
47
|
def quoted?(object)
|
55
|
-
|
56
|
-
when Arel::Nodes::SqlLiteral, Bignum, Fixnum
|
57
|
-
false
|
58
|
-
else
|
59
|
-
true
|
60
|
-
end
|
48
|
+
raise "not implemented"
|
61
49
|
end
|
62
50
|
|
63
51
|
def visit(object)
|
@@ -66,7 +54,7 @@ module Ransack
|
|
66
54
|
|
67
55
|
DISPATCH = Hash.new do |hash, klass|
|
68
56
|
hash[klass] = "visit_#{
|
69
|
-
klass.name.gsub(
|
57
|
+
klass.name.gsub(Constants::TWO_COLONS, Constants::UNDERSCORE)
|
70
58
|
}"
|
71
59
|
end
|
72
60
|
|
data/ransack.gemspec
CHANGED
@@ -11,6 +11,7 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.homepage = "https://github.com/activerecord-hackery/ransack"
|
12
12
|
s.summary = %q{Object-based searching for ActiveRecord (currently).}
|
13
13
|
s.description = %q{Ransack is the successor to the MetaSearch gem. It improves and expands upon MetaSearch's functionality, but does not have a 100%-compatible API.}
|
14
|
+
s.required_ruby_version = '>= 1.9'
|
14
15
|
s.license = 'MIT'
|
15
16
|
|
16
17
|
s.rubyforge_project = "ransack"
|
@@ -0,0 +1,276 @@
|
|
1
|
+
require 'mongoid_spec_helper'
|
2
|
+
|
3
|
+
module Ransack
|
4
|
+
module Adapters
|
5
|
+
module Mongoid
|
6
|
+
describe Base do
|
7
|
+
|
8
|
+
subject { Person }
|
9
|
+
|
10
|
+
it { should respond_to :ransack }
|
11
|
+
it { should respond_to :search }
|
12
|
+
|
13
|
+
describe '#search' do
|
14
|
+
subject { Person.search }
|
15
|
+
|
16
|
+
it { should be_a Search }
|
17
|
+
it 'has a Mongoid::Criteria as its object' do
|
18
|
+
expect(subject.object).to be_an ::Mongoid::Criteria
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'with scopes' do
|
22
|
+
before do
|
23
|
+
Person.stub :ransackable_scopes => [:active, :over_age]
|
24
|
+
end
|
25
|
+
|
26
|
+
it "applies true scopes" do
|
27
|
+
search = Person.search('active' => true)
|
28
|
+
expect(search.result.selector).to eq({ 'active' => 1 })
|
29
|
+
end
|
30
|
+
|
31
|
+
it "ignores unlisted scopes" do
|
32
|
+
search = Person.search('restricted' => true)
|
33
|
+
expect(search.result.selector).to_not eq({ 'restricted' => 1})
|
34
|
+
end
|
35
|
+
|
36
|
+
it "ignores false scopes" do
|
37
|
+
search = Person.search('active' => false)
|
38
|
+
expect(search.result.selector).to_not eq({ 'active' => 1 })
|
39
|
+
end
|
40
|
+
|
41
|
+
it "passes values to scopes" do
|
42
|
+
search = Person.search('over_age' => 18)
|
43
|
+
expect(search.result.selector).to eq({ 'age' => { '$gt' => 18 } })
|
44
|
+
end
|
45
|
+
|
46
|
+
it "chains scopes" do
|
47
|
+
search = Person.search('over_age' => 18, 'active' => true)
|
48
|
+
expect(search.result.selector).to eq({ 'age' => { '$gt' => 18 }, 'active' => 1 })
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe '#ransacker' do
|
54
|
+
# For infix tests
|
55
|
+
def self.sane_adapter?
|
56
|
+
case ::Mongoid::Document.connection.adapter_name
|
57
|
+
when "SQLite3", "PostgreSQL"
|
58
|
+
true
|
59
|
+
else
|
60
|
+
false
|
61
|
+
end
|
62
|
+
end
|
63
|
+
# # in schema.rb, class Person:
|
64
|
+
# ransacker :reversed_name, formatter: proc { |v| v.reverse } do |parent|
|
65
|
+
# parent.table[:name]
|
66
|
+
# end
|
67
|
+
|
68
|
+
# ransacker :doubled_name do |parent|
|
69
|
+
# Arel::Nodes::InfixOperation.new(
|
70
|
+
# '||', parent.table[:name], parent.table[:name]
|
71
|
+
# )
|
72
|
+
# end
|
73
|
+
|
74
|
+
it 'creates ransack attributes' do
|
75
|
+
s = Person.search(:reversed_name_eq => 'htimS cirA')
|
76
|
+
expect(s.result.size).to eq(Person.where(name: 'Aric Smith').count)
|
77
|
+
|
78
|
+
expect(s.result.first).to eq Person.where(name: 'Aric Smith').first
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'with joins' do
|
82
|
+
before { pending 'not implemented for mongoid' }
|
83
|
+
|
84
|
+
it 'can be accessed through associations' do
|
85
|
+
s = Person.search(:children_reversed_name_eq => 'htimS cirA')
|
86
|
+
expect(s.result.to_sql).to match(
|
87
|
+
/#{quote_table_name("children_people")}.#{
|
88
|
+
quote_column_name("name")} = 'Aric Smith'/
|
89
|
+
)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should keep proper key value pairs in the params hash" do
|
93
|
+
s = Person.search(:children_reversed_name_eq => 'Testing')
|
94
|
+
expect(s.result.to_sql).to match /LEFT OUTER JOIN/
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'allows an "attribute" to be an InfixOperation' do
|
100
|
+
s = Person.search(:doubled_name_eq => 'Aric SmithAric Smith')
|
101
|
+
expect(s.result.first).to eq Person.where(name: 'Aric Smith').first
|
102
|
+
end if defined?(Arel::Nodes::InfixOperation) && sane_adapter?
|
103
|
+
|
104
|
+
it "doesn't break #count if using InfixOperations" do
|
105
|
+
s = Person.search(:doubled_name_eq => 'Aric SmithAric Smith')
|
106
|
+
expect(s.result.count).to eq 1
|
107
|
+
end if defined?(Arel::Nodes::InfixOperation) && sane_adapter?
|
108
|
+
|
109
|
+
it "should remove empty key value pairs from the params hash" do
|
110
|
+
s = Person.search(:reversed_name_eq => '')
|
111
|
+
expect(s.result.selector).to eq({})
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should function correctly when nil is passed in" do
|
115
|
+
s = Person.search(nil)
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should function correctly when a blank string is passed in" do
|
119
|
+
s = Person.search('')
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should function correctly when using fields with dots in them" do
|
123
|
+
s = Person.search(:email_cont => "example.com")
|
124
|
+
expect(s.result.exists?).to be true
|
125
|
+
|
126
|
+
s = Person.search(:email_cont => "example.co.")
|
127
|
+
expect(s.result.exists?).not_to be true
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should function correctly when using fields with % in them" do
|
131
|
+
Person.create!(:name => "110%-er")
|
132
|
+
s = Person.search(:name_cont => "10%")
|
133
|
+
expect(s.result.exists?).to be true
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should function correctly when using fields with backslashes in them" do
|
137
|
+
Person.create!(:name => "\\WINNER\\")
|
138
|
+
s = Person.search(:name_cont => "\\WINNER\\")
|
139
|
+
expect(s.result.exists?).to be true
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'allows sort by "only_sort" field' do
|
143
|
+
pending "it doesn't work :("
|
144
|
+
s = Person.search(
|
145
|
+
"s" => { "0" => { "dir" => "desc", "name" => "only_sort" } }
|
146
|
+
)
|
147
|
+
expect(s.result.to_sql).to match(
|
148
|
+
/ORDER BY #{quote_table_name("people")}.#{
|
149
|
+
quote_column_name("only_sort")} ASC/
|
150
|
+
)
|
151
|
+
end
|
152
|
+
|
153
|
+
it "doesn't sort by 'only_search' field" do
|
154
|
+
pending "it doesn't work :("
|
155
|
+
s = Person.search(
|
156
|
+
"s" => { "0" => { "dir" => "asc", "name" => "only_search" } }
|
157
|
+
)
|
158
|
+
expect(s.result.to_sql).not_to match(
|
159
|
+
/ORDER BY #{quote_table_name("people")}.#{
|
160
|
+
quote_column_name("only_search")} ASC/
|
161
|
+
)
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'allows search by "only_search" field' do
|
165
|
+
s = Person.search(:only_search_eq => 'htimS cirA')
|
166
|
+
expect(s.result.selector).to eq({'only_search' => 'htimS cirA'})
|
167
|
+
end
|
168
|
+
|
169
|
+
it "can't be searched by 'only_sort'" do
|
170
|
+
s = Person.search(:only_sort_eq => 'htimS cirA')
|
171
|
+
expect(s.result.selector).not_to eq({'only_sort' => 'htimS cirA'})
|
172
|
+
end
|
173
|
+
|
174
|
+
it 'allows sort by "only_admin" field, if auth_object: :admin' do
|
175
|
+
s = Person.search(
|
176
|
+
{ "s" => { "0" => { "dir" => "asc", "name" => "only_admin" } } },
|
177
|
+
{ auth_object: :admin }
|
178
|
+
)
|
179
|
+
expect(s.result.options).to eq({ sort: { '_id' => -1, 'only_admin' => 1 } })
|
180
|
+
end
|
181
|
+
|
182
|
+
it "doesn't sort by 'only_admin' field, if auth_object: nil" do
|
183
|
+
s = Person.search(
|
184
|
+
"s" => { "0" => { "dir" => "asc", "name" => "only_admin" } }
|
185
|
+
)
|
186
|
+
expect(s.result.options).to eq({ sort: {'_id' => -1}})
|
187
|
+
end
|
188
|
+
|
189
|
+
it 'allows search by "only_admin" field, if auth_object: :admin' do
|
190
|
+
s = Person.search(
|
191
|
+
{ :only_admin_eq => 'htimS cirA' },
|
192
|
+
{ :auth_object => :admin }
|
193
|
+
)
|
194
|
+
expect(s.result.selector).to eq({ 'only_admin' => 'htimS cirA' })
|
195
|
+
end
|
196
|
+
|
197
|
+
it "can't be searched by 'only_admin', if auth_object: nil" do
|
198
|
+
s = Person.search(:only_admin_eq => 'htimS cirA')
|
199
|
+
expect(s.result.selector).to eq({})
|
200
|
+
end
|
201
|
+
|
202
|
+
it 'searches by id' do
|
203
|
+
ids = ['some_bson_id', 'another_bson_id']
|
204
|
+
s = Person.search(:id_in => ids)
|
205
|
+
expect(s.result.selector).to eq({ '_id' => { '$in' => ids } })
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
describe '#ransackable_attributes' do
|
210
|
+
context 'when auth_object is nil' do
|
211
|
+
subject { Person.ransackable_attributes }
|
212
|
+
|
213
|
+
it { should include 'name' }
|
214
|
+
it { should include 'reversed_name' }
|
215
|
+
it { should include 'doubled_name' }
|
216
|
+
it { should include 'only_search' }
|
217
|
+
it { should_not include 'only_sort' }
|
218
|
+
it { should_not include 'only_admin' }
|
219
|
+
end
|
220
|
+
|
221
|
+
context 'with auth_object :admin' do
|
222
|
+
subject { Person.ransackable_attributes(:admin) }
|
223
|
+
|
224
|
+
it { should include 'name' }
|
225
|
+
it { should include 'reversed_name' }
|
226
|
+
it { should include 'doubled_name' }
|
227
|
+
it { should include 'only_search' }
|
228
|
+
it { should_not include 'only_sort' }
|
229
|
+
it { should include 'only_admin' }
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
describe '#ransortable_attributes' do
|
234
|
+
context 'when auth_object is nil' do
|
235
|
+
subject { Person.ransortable_attributes }
|
236
|
+
|
237
|
+
it { should include 'name' }
|
238
|
+
it { should include 'reversed_name' }
|
239
|
+
it { should include 'doubled_name' }
|
240
|
+
it { should include 'only_sort' }
|
241
|
+
it { should_not include 'only_search' }
|
242
|
+
it { should_not include 'only_admin' }
|
243
|
+
end
|
244
|
+
|
245
|
+
context 'with auth_object :admin' do
|
246
|
+
subject { Person.ransortable_attributes(:admin) }
|
247
|
+
|
248
|
+
it { should include 'name' }
|
249
|
+
it { should include 'reversed_name' }
|
250
|
+
it { should include 'doubled_name' }
|
251
|
+
it { should include 'only_sort' }
|
252
|
+
it { should_not include 'only_search' }
|
253
|
+
it { should include 'only_admin' }
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
describe '#ransackable_associations' do
|
258
|
+
before { pending "not implemented for mongoid" }
|
259
|
+
|
260
|
+
subject { Person.ransackable_associations }
|
261
|
+
|
262
|
+
it { should include 'parent' }
|
263
|
+
it { should include 'children' }
|
264
|
+
it { should include 'articles' }
|
265
|
+
end
|
266
|
+
|
267
|
+
describe '#ransackable_scopes' do
|
268
|
+
subject { Person.ransackable_scopes }
|
269
|
+
|
270
|
+
it { should eq [] }
|
271
|
+
end
|
272
|
+
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|