ransack 1.1.0 → 1.2.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 +12 -4
- data/CONTRIBUTING.md +10 -4
- data/Gemfile +12 -9
- data/README.md +46 -11
- data/lib/ransack.rb +4 -2
- data/lib/ransack/adapters/active_record.rb +1 -1
- data/lib/ransack/adapters/active_record/3.0/compat.rb +16 -6
- data/lib/ransack/adapters/active_record/3.0/context.rb +32 -16
- data/lib/ransack/adapters/active_record/3.1/context.rb +32 -15
- data/lib/ransack/adapters/active_record/3.2/context.rb +1 -1
- data/lib/ransack/adapters/active_record/base.rb +9 -6
- data/lib/ransack/adapters/active_record/context.rb +193 -2
- data/lib/ransack/configuration.rb +4 -4
- data/lib/ransack/constants.rb +81 -18
- data/lib/ransack/context.rb +27 -12
- data/lib/ransack/helpers/form_builder.rb +126 -91
- data/lib/ransack/helpers/form_helper.rb +34 -12
- data/lib/ransack/naming.rb +2 -1
- data/lib/ransack/nodes/attribute.rb +6 -4
- data/lib/ransack/nodes/bindable.rb +3 -1
- data/lib/ransack/nodes/condition.rb +40 -27
- data/lib/ransack/nodes/grouping.rb +19 -13
- data/lib/ransack/nodes/node.rb +3 -3
- data/lib/ransack/nodes/sort.rb +5 -3
- data/lib/ransack/nodes/value.rb +2 -2
- data/lib/ransack/predicate.rb +18 -9
- data/lib/ransack/ransacker.rb +4 -4
- data/lib/ransack/search.rb +9 -12
- data/lib/ransack/translate.rb +42 -21
- data/lib/ransack/version.rb +1 -1
- data/lib/ransack/visitor.rb +4 -4
- data/ransack.gemspec +17 -7
- data/spec/blueprints/notes.rb +2 -0
- data/spec/blueprints/people.rb +4 -1
- data/spec/console.rb +3 -3
- data/spec/ransack/adapters/active_record/base_spec.rb +149 -22
- data/spec/ransack/adapters/active_record/context_spec.rb +5 -5
- data/spec/ransack/configuration_spec.rb +17 -8
- data/spec/ransack/dependencies_spec.rb +8 -0
- data/spec/ransack/helpers/form_builder_spec.rb +37 -14
- data/spec/ransack/helpers/form_helper_spec.rb +5 -5
- data/spec/ransack/predicate_spec.rb +6 -3
- data/spec/ransack/search_spec.rb +95 -73
- data/spec/ransack/translate_spec.rb +14 -0
- data/spec/spec_helper.rb +14 -8
- data/spec/support/en.yml +6 -0
- data/spec/support/schema.rb +76 -31
- metadata +48 -29
@@ -26,10 +26,11 @@ module Ransack
|
|
26
26
|
end
|
27
27
|
|
28
28
|
describe '#sort_link with default search_key' do
|
29
|
-
subject {
|
30
|
-
|
31
|
-
[:main_app, Person.search(:
|
32
|
-
:name,
|
29
|
+
subject { @controller.view_context.
|
30
|
+
sort_link(
|
31
|
+
[:main_app, Person.search(sorts: ['name desc'])],
|
32
|
+
:name,
|
33
|
+
controller: 'people'
|
33
34
|
)
|
34
35
|
}
|
35
36
|
it { should match(
|
@@ -75,7 +76,6 @@ module Ransack
|
|
75
76
|
}
|
76
77
|
end
|
77
78
|
|
78
|
-
|
79
79
|
context 'view has existing parameters' do
|
80
80
|
before do
|
81
81
|
@controller.view_context.params.merge!({ :exist => 'existing' })
|
@@ -22,14 +22,17 @@ module Ransack
|
|
22
22
|
describe 'eq' do
|
23
23
|
it 'generates an equality condition for boolean true' do
|
24
24
|
@s.awesome_eq = true
|
25
|
-
field = "#{quote_table_name("people")}.#{
|
26
|
-
|
25
|
+
field = "#{quote_table_name("people")}.#{
|
26
|
+
quote_column_name("awesome")}"
|
27
|
+
@s.result.to_sql.should match /#{field} = #{
|
28
|
+
ActiveRecord::Base.connection.quoted_true}/
|
27
29
|
end
|
28
30
|
|
29
31
|
it 'generates an equality condition for boolean false' do
|
30
32
|
@s.awesome_eq = false
|
31
33
|
field = "#{quote_table_name("people")}.#{quote_column_name("awesome")}"
|
32
|
-
@s.result.to_sql.should match /#{field} = #{
|
34
|
+
@s.result.to_sql.should match /#{field} = #{
|
35
|
+
ActiveRecord::Base.connection.quoted_false}/
|
33
36
|
end
|
34
37
|
|
35
38
|
it 'does not generate a condition for nil' do
|
data/spec/ransack/search_spec.rb
CHANGED
@@ -3,9 +3,15 @@ require 'spec_helper'
|
|
3
3
|
module Ransack
|
4
4
|
describe Search do
|
5
5
|
|
6
|
+
describe '#initialize' do
|
7
|
+
it 'does not raise exception for string :params argument' do
|
8
|
+
lambda { Search.new(Person, '') }.should_not raise_error
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
6
12
|
describe '#build' do
|
7
|
-
it 'creates
|
8
|
-
search = Search.new(Person, :
|
13
|
+
it 'creates conditions for top-level attributes' do
|
14
|
+
search = Search.new(Person, name_eq: 'Ernie')
|
9
15
|
condition = search.base[:name_eq]
|
10
16
|
condition.should be_a Nodes::Condition
|
11
17
|
condition.predicate.name.should eq 'eq'
|
@@ -13,8 +19,8 @@ module Ransack
|
|
13
19
|
condition.value.should eq 'Ernie'
|
14
20
|
end
|
15
21
|
|
16
|
-
it 'creates
|
17
|
-
search = Search.new(Person, :
|
22
|
+
it 'creates conditions for association attributes' do
|
23
|
+
search = Search.new(Person, children_name_eq: 'Ernie')
|
18
24
|
condition = search.base[:children_name_eq]
|
19
25
|
condition.should be_a Nodes::Condition
|
20
26
|
condition.predicate.name.should eq 'eq'
|
@@ -22,8 +28,8 @@ module Ransack
|
|
22
28
|
condition.value.should eq 'Ernie'
|
23
29
|
end
|
24
30
|
|
25
|
-
it 'creates
|
26
|
-
search = Search.new(Note, :
|
31
|
+
it 'creates conditions for polymorphic belongs_to association attributes' do
|
32
|
+
search = Search.new(Note, notable_of_Person_type_name_eq: 'Ernie')
|
27
33
|
condition = search.base[:notable_of_Person_type_name_eq]
|
28
34
|
condition.should be_a Nodes::Condition
|
29
35
|
condition.predicate.name.should eq 'eq'
|
@@ -31,9 +37,9 @@ module Ransack
|
|
31
37
|
condition.value.should eq 'Ernie'
|
32
38
|
end
|
33
39
|
|
34
|
-
it 'creates
|
40
|
+
it 'creates conditions for multiple polymorphic belongs_to association attributes' do
|
35
41
|
search = Search.new(Note,
|
36
|
-
:
|
42
|
+
notable_of_Person_type_name_or_notable_of_Article_type_title_eq: 'Ernie')
|
37
43
|
condition = search.
|
38
44
|
base[:notable_of_Person_type_name_or_notable_of_Article_type_title_eq]
|
39
45
|
condition.should be_a Nodes::Condition
|
@@ -44,16 +50,16 @@ module Ransack
|
|
44
50
|
end
|
45
51
|
|
46
52
|
it 'discards empty conditions' do
|
47
|
-
search = Search.new(Person, :
|
53
|
+
search = Search.new(Person, children_name_eq: '')
|
48
54
|
condition = search.base[:children_name_eq]
|
49
55
|
condition.should be_nil
|
50
56
|
end
|
51
57
|
|
52
58
|
it 'accepts arrays of groupings' do
|
53
59
|
search = Search.new(Person,
|
54
|
-
:
|
55
|
-
{ :
|
56
|
-
{ :
|
60
|
+
g: [
|
61
|
+
{ m: 'or', name_eq: 'Ernie', children_name_eq: 'Ernie' },
|
62
|
+
{ m: 'or', name_eq: 'Bert', children_name_eq: 'Bert' },
|
57
63
|
]
|
58
64
|
)
|
59
65
|
ors = search.groupings
|
@@ -67,9 +73,9 @@ module Ransack
|
|
67
73
|
|
68
74
|
it 'accepts "attributes" hashes for groupings' do
|
69
75
|
search = Search.new(Person,
|
70
|
-
:
|
71
|
-
'0' => { :
|
72
|
-
'1' => { :
|
76
|
+
g: {
|
77
|
+
'0' => { m: 'or', name_eq: 'Ernie', children_name_eq: 'Ernie' },
|
78
|
+
'1' => { m: 'or', name_eq: 'Bert', children_name_eq: 'Bert' },
|
73
79
|
}
|
74
80
|
)
|
75
81
|
ors = search.groupings
|
@@ -85,20 +91,22 @@ module Ransack
|
|
85
91
|
search = Search.new(Person,
|
86
92
|
:c => {
|
87
93
|
'0' => { :a => ['name'], :p => 'eq', :v => ['Ernie'] },
|
88
|
-
'1' => { :a => ['children_name', 'parent_name'],
|
89
|
-
|
94
|
+
'1' => { :a => ['children_name', 'parent_name'],
|
95
|
+
:p => 'eq', :v => ['Ernie'], :m => 'or' }
|
96
|
+
}
|
90
97
|
)
|
91
98
|
conditions = search.base.conditions
|
92
99
|
conditions.should have(2).items
|
93
|
-
conditions.map {|c| c.class}
|
100
|
+
conditions.map { |c| c.class }
|
101
|
+
.should eq [Nodes::Condition, Nodes::Condition]
|
94
102
|
end
|
95
103
|
|
96
|
-
it 'creates
|
104
|
+
it 'creates conditions for custom predicates that take arrays' do
|
97
105
|
Ransack.configure do |config|
|
98
106
|
config.add_predicate 'ary_pred', :wants_array => true
|
99
107
|
end
|
100
108
|
|
101
|
-
search = Search.new(Person, :
|
109
|
+
search = Search.new(Person, name_ary_pred: ['Ernie', 'Bert'])
|
102
110
|
condition = search.base[:name_ary_pred]
|
103
111
|
condition.should be_a Nodes::Condition
|
104
112
|
condition.predicate.name.should eq 'ary_pred'
|
@@ -107,56 +115,59 @@ module Ransack
|
|
107
115
|
end
|
108
116
|
|
109
117
|
it 'does not evaluate the query on #inspect' do
|
110
|
-
search = Search.new(Person, :
|
118
|
+
search = Search.new(Person, children_id_in: [1, 2, 3])
|
111
119
|
search.inspect.should_not match /ActiveRecord/
|
112
120
|
end
|
113
121
|
end
|
114
122
|
|
115
123
|
describe '#result' do
|
116
|
-
let(:people_name_field) {
|
117
|
-
|
124
|
+
let(:people_name_field) {
|
125
|
+
"#{quote_table_name("people")}.#{quote_column_name("name")}"
|
126
|
+
}
|
127
|
+
let(:children_people_name_field) {
|
128
|
+
"#{quote_table_name("children_people")}.#{quote_column_name("name")}"
|
129
|
+
}
|
118
130
|
it 'evaluates conditions contextually' do
|
119
|
-
search = Search.new(Person, :
|
131
|
+
search = Search.new(Person, children_name_eq: 'Ernie')
|
120
132
|
search.result.should be_an ActiveRecord::Relation
|
121
133
|
where = search.result.where_values.first
|
122
134
|
where.to_sql.should match /#{children_people_name_field} = 'Ernie'/
|
123
135
|
end
|
124
136
|
|
125
137
|
it 'evaluates compound conditions contextually' do
|
126
|
-
search = Search.new(Person, :
|
138
|
+
search = Search.new(Person, children_name_or_name_eq: 'Ernie')
|
127
139
|
search.result.should be_an ActiveRecord::Relation
|
128
140
|
where = search.result.where_values.first
|
129
|
-
where.to_sql.should match /#{children_people_name_field
|
141
|
+
where.to_sql.should match /#{children_people_name_field
|
142
|
+
} = 'Ernie' OR #{people_name_field} = 'Ernie'/
|
130
143
|
end
|
131
144
|
|
132
145
|
it 'evaluates polymorphic belongs_to association conditions contextually' do
|
133
|
-
search = Search.new(Note, :
|
146
|
+
search = Search.new(Note, notable_of_Person_type_name_eq: 'Ernie')
|
134
147
|
search.result.should be_an ActiveRecord::Relation
|
135
148
|
where = search.result.where_values.first
|
136
149
|
where.to_sql.should match /#{people_name_field} = 'Ernie'/
|
137
150
|
end
|
138
151
|
|
139
152
|
it 'evaluates nested conditions' do
|
140
|
-
search = Search.new(Person, :
|
141
|
-
:
|
142
|
-
{ :
|
143
|
-
:name_eq => 'Ernie',
|
144
|
-
:children_children_name_eq => 'Ernie'
|
145
|
-
}
|
153
|
+
search = Search.new(Person, children_name_eq: 'Ernie',
|
154
|
+
g: [
|
155
|
+
{ m: 'or', name_eq: 'Ernie', children_children_name_eq: 'Ernie' }
|
146
156
|
]
|
147
157
|
)
|
148
158
|
search.result.should be_an ActiveRecord::Relation
|
149
159
|
where = search.result.where_values.first
|
150
160
|
where.to_sql.should match /#{children_people_name_field} = 'Ernie'/
|
151
161
|
where.to_sql.should match /#{people_name_field} = 'Ernie'/
|
152
|
-
where.to_sql.should match /#{quote_table_name("children_people_2")
|
162
|
+
where.to_sql.should match /#{quote_table_name("children_people_2")
|
163
|
+
}.#{quote_column_name("name")} = 'Ernie'/
|
153
164
|
end
|
154
165
|
|
155
166
|
it 'evaluates arrays of groupings' do
|
156
167
|
search = Search.new(Person,
|
157
|
-
:
|
158
|
-
{ :
|
159
|
-
{ :
|
168
|
+
g: [
|
169
|
+
{ m: 'or', name_eq: 'Ernie', children_name_eq: 'Ernie'},
|
170
|
+
{ m: 'or', name_eq: 'Bert', children_name_eq: 'Bert'},
|
160
171
|
]
|
161
172
|
)
|
162
173
|
search.result.should be_an ActiveRecord::Relation
|
@@ -169,26 +180,42 @@ module Ransack
|
|
169
180
|
second.should match /#{children_people_name_field} = 'Bert'/
|
170
181
|
end
|
171
182
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
:
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
183
|
+
if ::ActiveRecord::VERSION::STRING >= "4"
|
184
|
+
it 'returns distinct records when passed distinct: true' do
|
185
|
+
search = Search.new(
|
186
|
+
Person, g: [
|
187
|
+
{ m: 'or',
|
188
|
+
comments_body_cont: 'e',
|
189
|
+
articles_comments_body_cont: 'e'
|
190
|
+
}
|
191
|
+
]
|
192
|
+
)
|
193
|
+
search.result.load.should have(9000).items
|
194
|
+
search.result(distinct: true).should have(10).items
|
195
|
+
search.result.load.uniq.should eq search.result(distinct: true).load
|
196
|
+
end
|
197
|
+
else
|
198
|
+
it 'returns distinct records when passed :distinct => true' do
|
199
|
+
search = Search.new(
|
200
|
+
Person, :g => [
|
201
|
+
{ :m => 'or',
|
202
|
+
:comments_body_cont => 'e',
|
203
|
+
:articles_comments_body_cont => 'e'
|
204
|
+
}
|
205
|
+
]
|
206
|
+
)
|
207
|
+
if ActiveRecord::VERSION::MAJOR == 3
|
208
|
+
all_or_load, uniq_or_distinct = :all, :uniq
|
209
|
+
else
|
210
|
+
all_or_load, uniq_or_distinct = :load, :distinct
|
211
|
+
end
|
212
|
+
search.result.send(all_or_load).
|
213
|
+
should have(9000).items
|
214
|
+
search.result(:distinct => true).
|
215
|
+
should have(10).items
|
216
|
+
search.result.send(all_or_load).send(uniq_or_distinct).
|
217
|
+
should eq search.result(:distinct => true).send(all_or_load)
|
185
218
|
end
|
186
|
-
search.result.send(all_or_load).
|
187
|
-
should have(920).items
|
188
|
-
search.result(:distinct => true).
|
189
|
-
should have(330).items
|
190
|
-
search.result.send(all_or_load).send(uniq_or_distinct).
|
191
|
-
should eq search.result(:distinct => true).send(all_or_load)
|
192
219
|
end
|
193
220
|
end
|
194
221
|
|
@@ -225,7 +252,7 @@ module Ransack
|
|
225
252
|
end
|
226
253
|
|
227
254
|
it 'creates sorts based on multiple attributes/directions in array format' do
|
228
|
-
@s.sorts = ['id desc', 'name asc']
|
255
|
+
@s.sorts = ['id desc', { name: 'name', dir: 'asc' }]
|
229
256
|
@s.sorts.should have(2).items
|
230
257
|
sort1, sort2 = @s.sorts
|
231
258
|
sort1.should be_a Nodes::Sort
|
@@ -237,7 +264,7 @@ module Ransack
|
|
237
264
|
end
|
238
265
|
|
239
266
|
it 'creates sorts based on multiple attributes and uppercase directions in array format' do
|
240
|
-
@s.sorts = ['id DESC', 'name ASC']
|
267
|
+
@s.sorts = ['id DESC', { name: 'name', dir: 'ASC' }]
|
241
268
|
@s.sorts.should have(2).items
|
242
269
|
sort1, sort2 = @s.sorts
|
243
270
|
sort1.should be_a Nodes::Sort
|
@@ -249,7 +276,7 @@ module Ransack
|
|
249
276
|
end
|
250
277
|
|
251
278
|
it 'creates sorts based on multiple attributes and different directions in array format' do
|
252
|
-
@s.sorts = ['id DESC', 'name']
|
279
|
+
@s.sorts = ['id DESC', { name: 'name', dir: nil }]
|
253
280
|
@s.sorts.should have(2).items
|
254
281
|
sort1, sort2 = @s.sorts
|
255
282
|
sort1.should be_a Nodes::Sort
|
@@ -262,8 +289,8 @@ module Ransack
|
|
262
289
|
|
263
290
|
it 'creates sorts based on multiple attributes/directions in hash format' do
|
264
291
|
@s.sorts = {
|
265
|
-
'0' => { :
|
266
|
-
'1' => { :
|
292
|
+
'0' => { name: 'id', dir: 'desc' },
|
293
|
+
'1' => { name: 'name', dir: 'asc' }
|
267
294
|
}
|
268
295
|
@s.sorts.should have(2).items
|
269
296
|
@s.sorts.should be_all { |s| Nodes::Sort === s }
|
@@ -275,8 +302,8 @@ module Ransack
|
|
275
302
|
|
276
303
|
it 'creates sorts based on multiple attributes and uppercase directions in hash format' do
|
277
304
|
@s.sorts = {
|
278
|
-
'0' => { :
|
279
|
-
'1' => { :
|
305
|
+
'0' => { name: 'id', dir: 'DESC' },
|
306
|
+
'1' => { name: 'name', dir: 'ASC' }
|
280
307
|
}
|
281
308
|
@s.sorts.should have(2).items
|
282
309
|
@s.sorts.should be_all { |s| Nodes::Sort === s }
|
@@ -288,8 +315,8 @@ module Ransack
|
|
288
315
|
|
289
316
|
it 'creates sorts based on multiple attributes and different directions in hash format' do
|
290
317
|
@s.sorts = {
|
291
|
-
'0' => { :
|
292
|
-
'1' => { :
|
318
|
+
'0' => { name: 'id', dir: 'DESC' },
|
319
|
+
'1' => { name: 'name', dir: nil }
|
293
320
|
}
|
294
321
|
@s.sorts.should have(2).items
|
295
322
|
@s.sorts.should be_all { |s| Nodes::Sort === s }
|
@@ -320,16 +347,11 @@ module Ransack
|
|
320
347
|
end
|
321
348
|
|
322
349
|
it 'allows chaining to access nested conditions' do
|
323
|
-
@s.groupings = [
|
350
|
+
@s.groupings = [
|
351
|
+
{ m: 'or', name_eq: 'Ernie', children_name_eq: 'Ernie' }
|
352
|
+
]
|
324
353
|
@s.groupings.first.children_name_eq.should eq 'Ernie'
|
325
354
|
end
|
326
355
|
end
|
327
|
-
|
328
|
-
describe '#respond_to' do
|
329
|
-
it 'is aware of second argument' do
|
330
|
-
Search.new(Person).respond_to?(:name_eq, true).should be_true
|
331
|
-
end
|
332
|
-
end
|
333
|
-
|
334
356
|
end
|
335
357
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Ransack
|
4
|
+
describe Translate do
|
5
|
+
|
6
|
+
describe '.attribute' do
|
7
|
+
it 'translate namespaced attribute like AR does' do
|
8
|
+
ar_translation = ::Namespace::Article.human_attribute_name(:title)
|
9
|
+
ransack_translation = Ransack::Translate.attribute(:title, :context => ::Namespace::Article.search.context)
|
10
|
+
ransack_translation.should eq ar_translation
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -6,17 +6,22 @@ require 'ransack'
|
|
6
6
|
Time.zone = 'Eastern Time (US & Canada)'
|
7
7
|
I18n.load_path += Dir[File.join(File.dirname(__FILE__), 'support', '*.yml')]
|
8
8
|
|
9
|
-
Dir[File.expand_path('../{helpers,support,blueprints}/*.rb', __FILE__)]
|
9
|
+
Dir[File.expand_path('../{helpers,support,blueprints}/*.rb', __FILE__)]
|
10
|
+
.each do |f|
|
10
11
|
require f
|
11
12
|
end
|
12
13
|
|
13
14
|
Sham.define do
|
14
|
-
name
|
15
|
-
title
|
16
|
-
body
|
17
|
-
salary
|
18
|
-
tag_name
|
19
|
-
note
|
15
|
+
name { Faker::Name.name }
|
16
|
+
title { Faker::Lorem.sentence }
|
17
|
+
body { Faker::Lorem.paragraph }
|
18
|
+
salary { |index| 30000 + (index * 1000) }
|
19
|
+
tag_name { Faker::Lorem.words(3).join(' ') }
|
20
|
+
note { Faker::Lorem.words(7).join(' ') }
|
21
|
+
only_admin { Faker::Lorem.words(3).join(' ') }
|
22
|
+
only_search { Faker::Lorem.words(3).join(' ') }
|
23
|
+
only_sort { Faker::Lorem.words(3).join(' ') }
|
24
|
+
notable_id { |id| id }
|
20
25
|
end
|
21
26
|
|
22
27
|
RSpec.configure do |config|
|
@@ -25,7 +30,8 @@ RSpec.configure do |config|
|
|
25
30
|
config.before(:suite) do
|
26
31
|
puts '=' * 80
|
27
32
|
connection_name = ActiveRecord::Base.connection.adapter_name
|
28
|
-
puts "Running specs against #{connection_name}, ActiveRecord #{
|
33
|
+
puts "Running specs against #{connection_name}, ActiveRecord #{
|
34
|
+
ActiveRecord::VERSION::STRING} and ARel #{Arel::VERSION}..."
|
29
35
|
puts '=' * 80
|
30
36
|
Schema.create
|
31
37
|
end
|
data/spec/support/en.yml
CHANGED
data/spec/support/schema.rb
CHANGED
@@ -26,24 +26,56 @@ class Person < ActiveRecord::Base
|
|
26
26
|
if ActiveRecord::VERSION::MAJOR == 3
|
27
27
|
default_scope order('id DESC')
|
28
28
|
else
|
29
|
-
default_scope { order(
|
30
|
-
# The new activerecord syntax "{ order(id: :desc) }" does not work
|
31
|
-
# with Ruby 1.8.7 which we still need to support for Rails 3
|
29
|
+
default_scope { order(id: :desc) }
|
32
30
|
end
|
33
|
-
belongs_to :parent, :
|
34
|
-
has_many :children, :
|
31
|
+
belongs_to :parent, class_name: 'Person', foreign_key: :parent_id
|
32
|
+
has_many :children, class_name: 'Person', foreign_key: :parent_id
|
35
33
|
has_many :articles
|
36
34
|
has_many :comments
|
37
|
-
has_many :authored_article_comments, :
|
38
|
-
|
39
|
-
has_many :notes, :
|
35
|
+
has_many :authored_article_comments, through: :articles,
|
36
|
+
source: :comments, foreign_key: :person_id
|
37
|
+
has_many :notes, as: :notable
|
40
38
|
|
41
|
-
ransacker :reversed_name, :
|
39
|
+
ransacker :reversed_name, formatter: proc { |v| v.reverse } do |parent|
|
42
40
|
parent.table[:name]
|
43
41
|
end
|
44
42
|
|
45
43
|
ransacker :doubled_name do |parent|
|
46
|
-
Arel::Nodes::InfixOperation.new(
|
44
|
+
Arel::Nodes::InfixOperation.new(
|
45
|
+
'||', parent.table[:name], parent.table[:name]
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.ransackable_attributes(auth_object = nil)
|
50
|
+
if auth_object == :admin
|
51
|
+
column_names + _ransackers.keys - ['only_sort']
|
52
|
+
else
|
53
|
+
column_names + _ransackers.keys - ['only_sort', 'only_admin']
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.ransortable_attributes(auth_object = nil)
|
58
|
+
if auth_object == :admin
|
59
|
+
column_names + _ransackers.keys - ['only_search']
|
60
|
+
else
|
61
|
+
column_names + _ransackers.keys - ['only_search', 'only_admin']
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.ransackable_attributes(auth_object = nil)
|
66
|
+
if auth_object == :admin
|
67
|
+
column_names + _ransackers.keys - ['only_sort']
|
68
|
+
else
|
69
|
+
column_names + _ransackers.keys - ['only_sort', 'only_admin']
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.ransortable_attributes(auth_object = nil)
|
74
|
+
if auth_object == :admin
|
75
|
+
column_names + _ransackers.keys - ['only_search']
|
76
|
+
else
|
77
|
+
column_names + _ransackers.keys - ['only_search', 'only_admin']
|
78
|
+
end
|
47
79
|
end
|
48
80
|
end
|
49
81
|
|
@@ -51,7 +83,19 @@ class Article < ActiveRecord::Base
|
|
51
83
|
belongs_to :person
|
52
84
|
has_many :comments
|
53
85
|
has_and_belongs_to_many :tags
|
54
|
-
has_many
|
86
|
+
has_many :notes, as: :notable
|
87
|
+
end
|
88
|
+
|
89
|
+
module Namespace
|
90
|
+
class Article < ::Article
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
module Namespace
|
96
|
+
class Article < ::Article
|
97
|
+
|
98
|
+
end
|
55
99
|
end
|
56
100
|
|
57
101
|
class Comment < ActiveRecord::Base
|
@@ -64,7 +108,7 @@ class Tag < ActiveRecord::Base
|
|
64
108
|
end
|
65
109
|
|
66
110
|
class Note < ActiveRecord::Base
|
67
|
-
belongs_to :notable, :
|
111
|
+
belongs_to :notable, polymorphic: true
|
68
112
|
end
|
69
113
|
|
70
114
|
module Schema
|
@@ -72,63 +116,64 @@ module Schema
|
|
72
116
|
ActiveRecord::Migration.verbose = false
|
73
117
|
|
74
118
|
ActiveRecord::Schema.define do
|
75
|
-
create_table :people, :
|
119
|
+
create_table :people, force: true do |t|
|
76
120
|
t.integer :parent_id
|
77
121
|
t.string :name
|
78
122
|
t.string :email
|
123
|
+
t.string :only_search
|
124
|
+
t.string :only_sort
|
125
|
+
t.string :only_admin
|
79
126
|
t.integer :salary
|
80
|
-
t.boolean :awesome, :
|
127
|
+
t.boolean :awesome, default: false
|
81
128
|
t.timestamps
|
82
129
|
end
|
83
130
|
|
84
|
-
create_table :articles, :
|
131
|
+
create_table :articles, force: true do |t|
|
85
132
|
t.integer :person_id
|
86
133
|
t.string :title
|
87
134
|
t.text :body
|
88
135
|
end
|
89
136
|
|
90
|
-
create_table :comments, :
|
137
|
+
create_table :comments, force: true do |t|
|
91
138
|
t.integer :article_id
|
92
139
|
t.integer :person_id
|
93
|
-
t.text
|
140
|
+
t.text :body
|
94
141
|
end
|
95
142
|
|
96
|
-
create_table :tags, :
|
143
|
+
create_table :tags, force: true do |t|
|
97
144
|
t.string :name
|
98
145
|
end
|
99
146
|
|
100
|
-
create_table :articles_tags, :
|
147
|
+
create_table :articles_tags, force: true, id: false do |t|
|
101
148
|
t.integer :article_id
|
102
149
|
t.integer :tag_id
|
103
150
|
end
|
104
151
|
|
105
|
-
create_table :notes, :
|
152
|
+
create_table :notes, force: true do |t|
|
106
153
|
t.integer :notable_id
|
107
|
-
t.string
|
108
|
-
t.string
|
154
|
+
t.string :notable_type
|
155
|
+
t.string :note
|
109
156
|
end
|
110
157
|
|
111
158
|
end
|
112
159
|
|
113
160
|
10.times do
|
114
161
|
person = Person.make
|
115
|
-
Note.make(:
|
162
|
+
Note.make(notable: person)
|
116
163
|
3.times do
|
117
|
-
article = Article.make(:
|
164
|
+
article = Article.make(person: person)
|
118
165
|
3.times do
|
119
166
|
article.tags = [Tag.make, Tag.make, Tag.make]
|
120
167
|
end
|
121
|
-
Note.make(:
|
168
|
+
Note.make(notable: article)
|
122
169
|
10.times do
|
123
|
-
Comment.make(:article
|
170
|
+
Comment.make(article: article, person: person)
|
124
171
|
end
|
125
172
|
end
|
126
|
-
2.times do
|
127
|
-
Comment.make(:person => person)
|
128
|
-
end
|
129
173
|
end
|
130
174
|
|
131
|
-
Comment.make(
|
132
|
-
|
175
|
+
Comment.make(
|
176
|
+
body: 'First post!', article: Article.make(title: 'Hello, world!')
|
177
|
+
)
|
133
178
|
end
|
134
179
|
end
|