ransack 1.2.3 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -4
- data/CONTRIBUTING.md +12 -4
- data/Gemfile +4 -5
- data/README.md +160 -55
- data/lib/ransack.rb +1 -1
- data/lib/ransack/adapters/active_record/3.0/context.rb +16 -0
- data/lib/ransack/adapters/active_record/3.1/context.rb +24 -0
- data/lib/ransack/adapters/active_record/base.rb +6 -0
- data/lib/ransack/adapters/active_record/context.rb +49 -1
- data/lib/ransack/configuration.rb +23 -6
- data/lib/ransack/constants.rb +46 -45
- data/lib/ransack/context.rb +19 -2
- data/lib/ransack/helpers/form_builder.rb +5 -4
- data/lib/ransack/helpers/form_helper.rb +34 -14
- data/lib/ransack/locale/hu.yml +70 -0
- data/lib/ransack/locale/nl.yml +70 -0
- data/lib/ransack/nodes/attribute.rb +2 -2
- data/lib/ransack/nodes/condition.rb +29 -12
- data/lib/ransack/nodes/grouping.rb +6 -6
- data/lib/ransack/nodes/node.rb +1 -1
- data/lib/ransack/nodes/value.rb +1 -1
- data/lib/ransack/predicate.rb +4 -5
- data/lib/ransack/ransacker.rb +1 -1
- data/lib/ransack/search.rb +39 -13
- data/lib/ransack/translate.rb +7 -8
- data/lib/ransack/version.rb +1 -1
- data/ransack.gemspec +5 -5
- data/spec/ransack/adapters/active_record/base_spec.rb +78 -35
- data/spec/ransack/adapters/active_record/context_spec.rb +58 -15
- data/spec/ransack/configuration_spec.rb +18 -18
- data/spec/ransack/dependencies_spec.rb +1 -1
- data/spec/ransack/helpers/form_builder_spec.rb +29 -29
- data/spec/ransack/helpers/form_helper_spec.rb +14 -1
- data/spec/ransack/nodes/condition_spec.rb +21 -2
- data/spec/ransack/predicate_spec.rb +49 -9
- data/spec/ransack/search_spec.rb +178 -143
- data/spec/ransack/translate_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -0
- data/spec/support/schema.rb +26 -21
- metadata +15 -11
data/lib/ransack/version.rb
CHANGED
data/ransack.gemspec
CHANGED
@@ -6,8 +6,8 @@ Gem::Specification.new do |s|
|
|
6
6
|
s.name = "ransack"
|
7
7
|
s.version = Ransack::VERSION
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
|
-
s.authors = ["Ernie Miller", "Ryan Bigg"]
|
10
|
-
s.email = ["ernie@erniemiller.org", "radarlistener@gmail.com"]
|
9
|
+
s.authors = ["Ernie Miller", "Ryan Bigg", "Jon Atack"]
|
10
|
+
s.email = ["ernie@erniemiller.org", "radarlistener@gmail.com", "jonnyatack@gmail.com"]
|
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.}
|
@@ -19,12 +19,12 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.add_dependency 'activerecord', '>= 3.0'
|
20
20
|
s.add_dependency 'activesupport', '>= 3.0'
|
21
21
|
s.add_dependency 'i18n'
|
22
|
-
s.add_dependency 'polyamorous', '~> 1.
|
23
|
-
s.add_development_dependency 'rspec', '~> 2.
|
22
|
+
s.add_dependency 'polyamorous', '~> 1.1'
|
23
|
+
s.add_development_dependency 'rspec', '~> 2.14.0'
|
24
24
|
s.add_development_dependency 'machinist', '~> 1.0.6'
|
25
25
|
s.add_development_dependency 'faker', '~> 0.9.5'
|
26
26
|
s.add_development_dependency 'sqlite3', '~> 1.3.3'
|
27
|
-
s.add_development_dependency 'pg'
|
27
|
+
s.add_development_dependency 'pg'
|
28
28
|
s.add_development_dependency 'mysql2', '0.3.14'
|
29
29
|
s.add_development_dependency 'pry', '0.9.12.2'
|
30
30
|
|
@@ -15,8 +15,41 @@ module Ransack
|
|
15
15
|
|
16
16
|
it { should be_a Search }
|
17
17
|
it 'has a Relation as its object' do
|
18
|
-
subject.object.
|
18
|
+
expect(subject.object).to be_an ::ActiveRecord::Relation
|
19
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
|
+
search.result.to_sql.should include "active = 1"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "ignores unlisted scopes" do
|
32
|
+
search = Person.search('restricted' => true)
|
33
|
+
search.result.to_sql.should_not include "restricted"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "ignores false scopes" do
|
37
|
+
search = Person.search('active' => false)
|
38
|
+
search.result.to_sql.should_not include "active"
|
39
|
+
end
|
40
|
+
|
41
|
+
it "passes values to scopes" do
|
42
|
+
search = Person.search('over_age' => 18)
|
43
|
+
search.result.to_sql.should include "age > 18"
|
44
|
+
end
|
45
|
+
|
46
|
+
it "chains scopes" do
|
47
|
+
search = Person.search('over_age' => 18, 'active' => true)
|
48
|
+
search.result.to_sql.should include "age > 18"
|
49
|
+
search.result.to_sql.should include "active = 1"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
20
53
|
end
|
21
54
|
|
22
55
|
describe '#ransacker' do
|
@@ -41,66 +74,70 @@ module Ransack
|
|
41
74
|
# end
|
42
75
|
|
43
76
|
it 'creates ransack attributes' do
|
44
|
-
s = Person.search(reversed_name_eq
|
45
|
-
s.result.
|
77
|
+
s = Person.search(:reversed_name_eq => 'htimS cirA')
|
78
|
+
expect(s.result.size).to eq(1)
|
46
79
|
|
47
|
-
s.result.first.
|
80
|
+
expect(s.result.first).to eq Person.where(name: 'Aric Smith').first
|
48
81
|
end
|
49
82
|
|
50
83
|
it 'can be accessed through associations' do
|
51
|
-
s = Person.search(children_reversed_name_eq
|
52
|
-
s.result.to_sql.
|
84
|
+
s = Person.search(:children_reversed_name_eq => 'htimS cirA')
|
85
|
+
expect(s.result.to_sql).to match(
|
53
86
|
/#{quote_table_name("children_people")}.#{
|
54
87
|
quote_column_name("name")} = 'Aric Smith'/
|
55
88
|
)
|
56
89
|
end
|
57
90
|
|
58
91
|
it 'allows an "attribute" to be an InfixOperation' do
|
59
|
-
s = Person.search(doubled_name_eq
|
60
|
-
s.result.first.
|
92
|
+
s = Person.search(:doubled_name_eq => 'Aric SmithAric Smith')
|
93
|
+
expect(s.result.first).to eq Person.where(name: 'Aric Smith').first
|
61
94
|
end if defined?(Arel::Nodes::InfixOperation) && sane_adapter?
|
62
95
|
|
63
96
|
it "doesn't break #count if using InfixOperations" do
|
64
|
-
s = Person.search(doubled_name_eq
|
65
|
-
s.result.count.
|
97
|
+
s = Person.search(:doubled_name_eq => 'Aric SmithAric Smith')
|
98
|
+
expect(s.result.count).to eq 1
|
66
99
|
end if defined?(Arel::Nodes::InfixOperation) && sane_adapter?
|
67
100
|
|
68
101
|
it "should remove empty key value pairs from the params hash" do
|
69
|
-
s = Person.search(children_reversed_name_eq
|
70
|
-
s.result.to_sql.
|
102
|
+
s = Person.search(:children_reversed_name_eq => '')
|
103
|
+
expect(s.result.to_sql).not_to match /LEFT OUTER JOIN/
|
71
104
|
end
|
72
105
|
|
73
106
|
it "should keep proper key value pairs in the params hash" do
|
74
|
-
s = Person.search(children_reversed_name_eq
|
75
|
-
s.result.to_sql.
|
107
|
+
s = Person.search(:children_reversed_name_eq => 'Testing')
|
108
|
+
expect(s.result.to_sql).to match /LEFT OUTER JOIN/
|
76
109
|
end
|
77
110
|
|
78
111
|
it "should function correctly when nil is passed in" do
|
79
112
|
s = Person.search(nil)
|
80
113
|
end
|
81
114
|
|
115
|
+
it "should function correctly when a blank string is passed in" do
|
116
|
+
s = Person.search('')
|
117
|
+
end
|
118
|
+
|
82
119
|
it "should function correctly when using fields with dots in them" do
|
83
|
-
s = Person.search(email_cont
|
84
|
-
s.result.exists
|
120
|
+
s = Person.search(:email_cont => "example.com")
|
121
|
+
expect(s.result.exists?).to be true
|
85
122
|
end
|
86
123
|
|
87
124
|
it "should function correctly when using fields with % in them" do
|
88
|
-
Person.create!(name
|
89
|
-
s = Person.search(name_cont
|
90
|
-
s.result.exists
|
125
|
+
Person.create!(:name => "110%-er")
|
126
|
+
s = Person.search(:name_cont => "10%")
|
127
|
+
expect(s.result.exists?).to be true
|
91
128
|
end
|
92
129
|
|
93
130
|
it "should function correctly when using fields with backslashes in them" do
|
94
|
-
Person.create!(name
|
95
|
-
s = Person.search(name_cont
|
96
|
-
s.result.exists
|
131
|
+
Person.create!(:name => "\\WINNER\\")
|
132
|
+
s = Person.search(:name_cont => "\\WINNER\\")
|
133
|
+
expect(s.result.exists?).to be true
|
97
134
|
end
|
98
135
|
|
99
136
|
it 'allows sort by "only_sort" field' do
|
100
137
|
s = Person.search(
|
101
138
|
"s" => { "0" => { "dir" => "asc", "name" => "only_sort" } }
|
102
139
|
)
|
103
|
-
s.result.to_sql.
|
140
|
+
expect(s.result.to_sql).to match(
|
104
141
|
/ORDER BY #{quote_table_name("people")}.#{
|
105
142
|
quote_column_name("only_sort")} ASC/
|
106
143
|
)
|
@@ -110,23 +147,23 @@ module Ransack
|
|
110
147
|
s = Person.search(
|
111
148
|
"s" => { "0" => { "dir" => "asc", "name" => "only_search" } }
|
112
149
|
)
|
113
|
-
s.result.to_sql.
|
150
|
+
expect(s.result.to_sql).not_to match(
|
114
151
|
/ORDER BY #{quote_table_name("people")}.#{
|
115
152
|
quote_column_name("only_search")} ASC/
|
116
153
|
)
|
117
154
|
end
|
118
155
|
|
119
156
|
it 'allows search by "only_search" field' do
|
120
|
-
s = Person.search(only_search_eq
|
121
|
-
s.result.to_sql.
|
157
|
+
s = Person.search(:only_search_eq => 'htimS cirA')
|
158
|
+
expect(s.result.to_sql).to match(
|
122
159
|
/WHERE #{quote_table_name("people")}.#{
|
123
160
|
quote_column_name("only_search")} = 'htimS cirA'/
|
124
161
|
)
|
125
162
|
end
|
126
163
|
|
127
164
|
it "can't be searched by 'only_sort'" do
|
128
|
-
s = Person.search(only_sort_eq
|
129
|
-
s.result.to_sql.
|
165
|
+
s = Person.search(:only_sort_eq => 'htimS cirA')
|
166
|
+
expect(s.result.to_sql).not_to match(
|
130
167
|
/WHERE #{quote_table_name("people")}.#{
|
131
168
|
quote_column_name("only_sort")} = 'htimS cirA'/
|
132
169
|
)
|
@@ -137,7 +174,7 @@ module Ransack
|
|
137
174
|
{ "s" => { "0" => { "dir" => "asc", "name" => "only_admin" } } },
|
138
175
|
{ auth_object: :admin }
|
139
176
|
)
|
140
|
-
s.result.to_sql.
|
177
|
+
expect(s.result.to_sql).to match(
|
141
178
|
/ORDER BY #{quote_table_name("people")}.#{
|
142
179
|
quote_column_name("only_admin")} ASC/
|
143
180
|
)
|
@@ -147,7 +184,7 @@ module Ransack
|
|
147
184
|
s = Person.search(
|
148
185
|
"s" => { "0" => { "dir" => "asc", "name" => "only_admin" } }
|
149
186
|
)
|
150
|
-
s.result.to_sql.
|
187
|
+
expect(s.result.to_sql).not_to match(
|
151
188
|
/ORDER BY #{quote_table_name("people")}.#{
|
152
189
|
quote_column_name("only_admin")} ASC/
|
153
190
|
)
|
@@ -155,18 +192,18 @@ module Ransack
|
|
155
192
|
|
156
193
|
it 'allows search by "only_admin" field, if auth_object: :admin' do
|
157
194
|
s = Person.search(
|
158
|
-
{ only_admin_eq
|
159
|
-
{ auth_object
|
195
|
+
{ :only_admin_eq => 'htimS cirA' },
|
196
|
+
{ :auth_object => :admin }
|
160
197
|
)
|
161
|
-
s.result.to_sql.
|
198
|
+
expect(s.result.to_sql).to match(
|
162
199
|
/WHERE #{quote_table_name("people")}.#{
|
163
200
|
quote_column_name("only_admin")} = 'htimS cirA'/
|
164
201
|
)
|
165
202
|
end
|
166
203
|
|
167
204
|
it "can't be searched by 'only_admin', if auth_object: nil" do
|
168
|
-
s = Person.search(only_admin_eq
|
169
|
-
s.result.to_sql.
|
205
|
+
s = Person.search(:only_admin_eq => 'htimS cirA')
|
206
|
+
expect(s.result.to_sql).not_to match(
|
170
207
|
/WHERE #{quote_table_name("people")}.#{
|
171
208
|
quote_column_name("only_admin")} = 'htimS cirA'/
|
172
209
|
)
|
@@ -229,6 +266,12 @@ module Ransack
|
|
229
266
|
it { should include 'articles' }
|
230
267
|
end
|
231
268
|
|
269
|
+
describe '#ransackable_scopes' do
|
270
|
+
subject { Person.ransackable_scopes }
|
271
|
+
|
272
|
+
it { should eq [] }
|
273
|
+
end
|
274
|
+
|
232
275
|
end
|
233
276
|
end
|
234
277
|
end
|
@@ -6,43 +6,86 @@ module Ransack
|
|
6
6
|
describe Context do
|
7
7
|
subject { Context.new(Person) }
|
8
8
|
|
9
|
+
if ::ActiveRecord::VERSION::STRING >= "3.1"
|
10
|
+
its(:alias_tracker) { should be_a ::ActiveRecord::Associations::AliasTracker }
|
11
|
+
end
|
12
|
+
|
9
13
|
describe '#relation_for' do
|
10
14
|
it 'returns relation for given object' do
|
11
|
-
subject.object.
|
15
|
+
expect(subject.object).to be_an ::ActiveRecord::Relation
|
12
16
|
end
|
13
17
|
end
|
14
18
|
|
15
19
|
describe '#evaluate' do
|
16
20
|
it 'evaluates search objects' do
|
17
|
-
search = Search.new(Person, name_eq
|
21
|
+
search = Search.new(Person, :name_eq => 'Joe Blow')
|
18
22
|
result = subject.evaluate(search)
|
19
23
|
|
20
|
-
result.
|
21
|
-
result.to_sql.
|
24
|
+
expect(result).to be_an ::ActiveRecord::Relation
|
25
|
+
expect(result.to_sql).to match /#{quote_column_name("name")} = 'Joe Blow'/
|
22
26
|
end
|
23
27
|
|
24
28
|
it 'SELECTs DISTINCT when distinct: true' do
|
25
|
-
search = Search.new(Person, name_eq
|
26
|
-
result = subject.evaluate(search, distinct
|
29
|
+
search = Search.new(Person, :name_eq => 'Joe Blow')
|
30
|
+
result = subject.evaluate(search, :distinct => true)
|
31
|
+
|
32
|
+
expect(result).to be_an ::ActiveRecord::Relation
|
33
|
+
expect(result.to_sql).to match /SELECT DISTINCT/
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "sharing context across searches" do
|
38
|
+
let(:shared_context) { Context.for(Person) }
|
39
|
+
|
40
|
+
before do
|
41
|
+
Search.new(Person, {:parent_name_eq => 'A'}, context: shared_context)
|
42
|
+
Search.new(Person, {:children_name_eq => 'B'}, context: shared_context)
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#join_associations', :if => ::ActiveRecord::VERSION::STRING <= '4.0' do
|
46
|
+
it 'returns dependent join associations for all searches run against the context' do
|
47
|
+
parents, children = shared_context.join_associations
|
48
|
+
|
49
|
+
expect(children.aliased_table_name).to eq "children_people"
|
50
|
+
expect(parents.aliased_table_name).to eq "parents_people"
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'can be rejoined to execute a valid query' do
|
54
|
+
parents, children = shared_context.join_associations
|
55
|
+
|
56
|
+
expect { Person.joins(parents).joins(children).to_a }.to_not raise_error
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '#join_sources', :if => ::ActiveRecord::VERSION::STRING >= '3.1' do
|
61
|
+
it 'returns dependent arel join nodes for all searches run against the context' do
|
62
|
+
parents, children = shared_context.join_sources
|
63
|
+
|
64
|
+
expect(children.left.name).to eq "children_people"
|
65
|
+
expect(parents.left.name).to eq "parents_people"
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'can be rejoined to execute a valid query' do
|
69
|
+
parents, children = shared_context.join_sources
|
27
70
|
|
28
|
-
|
29
|
-
|
71
|
+
expect { Person.joins(parents).joins(children).to_a }.to_not raise_error
|
72
|
+
end
|
30
73
|
end
|
31
74
|
end
|
32
75
|
|
33
76
|
it 'contextualizes strings to attributes' do
|
34
77
|
attribute = subject.contextualize 'children_children_parent_name'
|
35
|
-
attribute.
|
36
|
-
attribute.name.to_s.
|
37
|
-
attribute.relation.table_alias.
|
78
|
+
expect(attribute).to be_a Arel::Attributes::Attribute
|
79
|
+
expect(attribute.name.to_s).to eq 'name'
|
80
|
+
expect(attribute.relation.table_alias).to eq 'parents_people'
|
38
81
|
end
|
39
82
|
|
40
83
|
it 'builds new associations if not yet built' do
|
41
84
|
attribute = subject.contextualize 'children_articles_title'
|
42
|
-
attribute.
|
43
|
-
attribute.name.to_s.
|
44
|
-
attribute.relation.name.
|
45
|
-
attribute.relation.table_alias.
|
85
|
+
expect(attribute).to be_a Arel::Attributes::Attribute
|
86
|
+
expect(attribute.name.to_s).to eq 'title'
|
87
|
+
expect(attribute.relation.name).to eq 'articles'
|
88
|
+
expect(attribute.relation.table_alias).to be_nil
|
46
89
|
end
|
47
90
|
|
48
91
|
end
|
@@ -4,7 +4,7 @@ module Ransack
|
|
4
4
|
describe Configuration do
|
5
5
|
it 'yields Ransack on configure' do
|
6
6
|
Ransack.configure do |config|
|
7
|
-
config.
|
7
|
+
expect(config).to eq Ransack
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
@@ -13,28 +13,28 @@ module Ransack
|
|
13
13
|
config.add_predicate :test_predicate
|
14
14
|
end
|
15
15
|
|
16
|
-
Ransack.predicates.
|
17
|
-
Ransack.predicates.
|
18
|
-
Ransack.predicates.
|
16
|
+
expect(Ransack.predicates).to have_key 'test_predicate'
|
17
|
+
expect(Ransack.predicates).to have_key 'test_predicate_any'
|
18
|
+
expect(Ransack.predicates).to have_key 'test_predicate_all'
|
19
19
|
end
|
20
20
|
|
21
21
|
it 'avoids creating compound predicates if compounds: false' do
|
22
22
|
Ransack.configure do |config|
|
23
23
|
config.add_predicate(
|
24
24
|
:test_predicate_without_compound,
|
25
|
-
compounds
|
25
|
+
:compounds => false
|
26
26
|
)
|
27
27
|
end
|
28
|
-
Ransack.predicates
|
29
|
-
.
|
30
|
-
Ransack.predicates
|
31
|
-
.
|
32
|
-
Ransack.predicates
|
33
|
-
.
|
28
|
+
expect(Ransack.predicates)
|
29
|
+
.to have_key 'test_predicate_without_compound'
|
30
|
+
expect(Ransack.predicates)
|
31
|
+
.not_to have_key 'test_predicate_without_compound_any'
|
32
|
+
expect(Ransack.predicates)
|
33
|
+
.not_to have_key 'test_predicate_without_compound_all'
|
34
34
|
end
|
35
35
|
|
36
36
|
it 'should have default value for search key' do
|
37
|
-
Ransack.options[:search_key].
|
37
|
+
expect(Ransack.options[:search_key]).to eq :q
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'changes default search key parameter' do
|
@@ -45,7 +45,7 @@ module Ransack
|
|
45
45
|
config.search_key = :query
|
46
46
|
end
|
47
47
|
|
48
|
-
Ransack.options[:search_key].
|
48
|
+
expect(Ransack.options[:search_key]).to eq :query
|
49
49
|
|
50
50
|
# restore original state so we don't break other tests
|
51
51
|
Ransack.options = before
|
@@ -55,14 +55,14 @@ module Ransack
|
|
55
55
|
Ransack.configure do |config|
|
56
56
|
config.add_predicate(
|
57
57
|
:test_array_predicate,
|
58
|
-
wants_array
|
59
|
-
compounds
|
58
|
+
:wants_array => true,
|
59
|
+
:compounds => true
|
60
60
|
)
|
61
61
|
end
|
62
62
|
|
63
|
-
Ransack.predicates['test_array_predicate'].wants_array.
|
64
|
-
Ransack.predicates.
|
65
|
-
Ransack.predicates.
|
63
|
+
expect(Ransack.predicates['test_array_predicate'].wants_array).to eq true
|
64
|
+
expect(Ransack.predicates).not_to have_key 'test_array_predicate_any'
|
65
|
+
expect(Ransack.predicates).not_to have_key 'test_array_predicate_all'
|
66
66
|
end
|
67
67
|
end
|
68
68
|
end
|
@@ -35,11 +35,11 @@ module Ransack
|
|
35
35
|
@s.created_at_eq = [2011, 1, 2, 3, 4, 5]
|
36
36
|
html = @f.datetime_select(
|
37
37
|
:created_at_eq,
|
38
|
-
use_month_numbers
|
39
|
-
include_seconds
|
38
|
+
:use_month_numbers => true,
|
39
|
+
:include_seconds => true
|
40
40
|
)
|
41
41
|
%w(2011 1 2 03 04 05).each do |val|
|
42
|
-
html.
|
42
|
+
expect(html).to match /<option selected="selected" value="#{val}">#{val}<\/option>/
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
@@ -47,26 +47,26 @@ module Ransack
|
|
47
47
|
|
48
48
|
it 'localizes attribute names' do
|
49
49
|
html = @f.label :name_cont
|
50
|
-
html.
|
50
|
+
expect(html).to match /Full Name contains/
|
51
51
|
end
|
52
52
|
|
53
53
|
end
|
54
54
|
|
55
55
|
describe '#sort_link' do
|
56
56
|
it 'sort_link for ransack attribute' do
|
57
|
-
sort_link = @f.sort_link :name, controller
|
58
|
-
if ActiveRecord::VERSION::STRING =~ /^3\.[1-2]\./
|
59
|
-
sort_link.
|
57
|
+
sort_link = @f.sort_link :name, :controller => 'people'
|
58
|
+
if ActiveRecord::VERSION::STRING =~ /^3\.[1-2]\./
|
59
|
+
expect(sort_link).to match /people\?q%5Bs%5D=name\+asc/
|
60
60
|
else
|
61
|
-
sort_link.
|
61
|
+
expect(sort_link).to match /people\?q(%5B|\[)s(%5D|\])=name\+asc/
|
62
62
|
end
|
63
|
-
sort_link.
|
64
|
-
sort_link.
|
63
|
+
expect(sort_link).to match /sort_link/
|
64
|
+
expect(sort_link).to match /Full Name<\/a>/
|
65
65
|
end
|
66
66
|
|
67
67
|
it 'sort_link for common attribute' do
|
68
|
-
sort_link = @f.sort_link :id, controller
|
69
|
-
sort_link.
|
68
|
+
sort_link = @f.sort_link :id, :controller => 'people'
|
69
|
+
expect(sort_link).to match /id<\/a>/
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
@@ -74,7 +74,7 @@ module Ransack
|
|
74
74
|
|
75
75
|
it 'localizes :search when no default value given' do
|
76
76
|
html = @f.submit
|
77
|
-
html.
|
77
|
+
expect(html).to match /"Search"/
|
78
78
|
end
|
79
79
|
|
80
80
|
end
|
@@ -83,27 +83,27 @@ module Ransack
|
|
83
83
|
|
84
84
|
it 'returns ransackable attributes' do
|
85
85
|
html = @f.attribute_select
|
86
|
-
html.split(/\n/).
|
87
|
-
|
86
|
+
expect(html.split(/\n/).size).
|
87
|
+
to eq(Person.ransackable_attributes.size + 1)
|
88
88
|
Person.ransackable_attributes.each do |attribute|
|
89
|
-
html.
|
89
|
+
expect(html).to match /<option value="#{attribute}">/
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
93
93
|
it 'returns ransackable attributes for associations with :associations' do
|
94
94
|
attributes = Person.ransackable_attributes + Article.
|
95
95
|
ransackable_attributes.map { |a| "articles_#{a}" }
|
96
|
-
html = @f.attribute_select(associations
|
97
|
-
html.split(/\n/).
|
96
|
+
html = @f.attribute_select(:associations => ['articles'])
|
97
|
+
expect(html.split(/\n/).size).to eq(attributes.size)
|
98
98
|
attributes.each do |attribute|
|
99
|
-
html.
|
99
|
+
expect(html).to match /<option value="#{attribute}">/
|
100
100
|
end
|
101
101
|
end
|
102
102
|
|
103
103
|
it 'returns option groups for base and associations with :associations' do
|
104
|
-
html = @f.attribute_select(associations
|
104
|
+
html = @f.attribute_select(:associations => ['articles'])
|
105
105
|
[Person, Article].each do |model|
|
106
|
-
html.
|
106
|
+
expect(html).to match /<optgroup label="#{model}">/
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
@@ -114,28 +114,28 @@ module Ransack
|
|
114
114
|
it 'returns predicates with predicate_select' do
|
115
115
|
html = @f.predicate_select
|
116
116
|
Predicate.names.each do |key|
|
117
|
-
html.
|
117
|
+
expect(html).to match /<option value="#{key}">/
|
118
118
|
end
|
119
119
|
end
|
120
120
|
|
121
121
|
it 'filters predicates with single-value :only' do
|
122
|
-
html = @f.predicate_select only
|
122
|
+
html = @f.predicate_select :only => 'eq'
|
123
123
|
Predicate.names.reject { |k| k =~ /^eq/ }.each do |key|
|
124
|
-
html.
|
124
|
+
expect(html).not_to match /<option value="#{key}">/
|
125
125
|
end
|
126
126
|
end
|
127
127
|
|
128
128
|
it 'filters predicates with multi-value :only' do
|
129
129
|
html = @f.predicate_select only: [:eq, :lt]
|
130
130
|
Predicate.names.reject { |k| k =~ /^(eq|lt)/ }.each do |key|
|
131
|
-
html.
|
131
|
+
expect(html).not_to match /<option value="#{key}">/
|
132
132
|
end
|
133
133
|
end
|
134
134
|
|
135
135
|
it 'excludes compounds when compounds: false' do
|
136
|
-
html = @f.predicate_select compounds
|
136
|
+
html = @f.predicate_select :compounds => false
|
137
137
|
Predicate.names.select { |k| k =~ /_(any|all)$/ }.each do |key|
|
138
|
-
html.
|
138
|
+
expect(html).not_to match /<option value="#{key}">/
|
139
139
|
end
|
140
140
|
end
|
141
141
|
end
|
@@ -148,11 +148,11 @@ module Ransack
|
|
148
148
|
end
|
149
149
|
it 'accepts poly_id field' do
|
150
150
|
html = @f.text_field(:notable_id_eq)
|
151
|
-
html.
|
151
|
+
expect(html).to match /id=\"q_notable_id_eq\"/
|
152
152
|
end
|
153
153
|
it 'accepts poly_type field' do
|
154
154
|
html = @f.text_field(:notable_type_eq)
|
155
|
-
html.
|
155
|
+
expect(html).to match /id=\"q_notable_type_eq\"/
|
156
156
|
end
|
157
157
|
end
|
158
158
|
end
|