itrigga-param_fu 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.1
1
+ 0.4.2
@@ -57,10 +57,12 @@ module Trigga
57
57
  end
58
58
 
59
59
  # Give this a hash per model in the format:
60
+ #
60
61
  # Model class => { param_name => { :operator=>(db operator - defaults to '='),
61
62
  # => :field_name=>(field_name in the database - defaults to param_name)
62
63
  # => }
63
64
  # => }
65
+ #
64
66
  # and it will return an ActiveRecord finder :conditions clause using any params which are present in the given :params
65
67
  # e.g. if you have params = { :created_date_from=>'2011-10-09 00:01:02', :status=>'A', :click_url=>'items.html' }
66
68
  # then calling:
@@ -78,8 +80,41 @@ module Trigga
78
80
  #
79
81
  # [ 'clicks.request_path like (?) AND clicks.status = ? AND clicks.created_date_from >= ?', '%items.html%', 'A', '2011-10-09 00:01:02' ]
80
82
  #
83
+ #
81
84
  # It will ignore any criteria given which are NOT in the given :params hash
82
85
  #
86
+ # Table Names
87
+ # ===========
88
+ # By default each field given in a model class key is automatically scoped by the table name - e.g.
89
+ #
90
+ # Person => { :status=>{} }
91
+ #
92
+ # results in a where clause of
93
+ #
94
+ # 'people.status = (?)'
95
+ #
96
+ # Sometimes you need to scope a field by another table name - e.g. when you have a joined table, or an aliased table
97
+ # If your fieldname contains a dot ('.') it will NOT be scoped by the table name, it will be left as given
98
+ #
99
+ # e.g.
100
+ #
101
+ # Writer => { :interested_in => { :operator => 'LIKE', :field_name=>['writer_interests.interest_notes'] }}
102
+ #
103
+ # gives
104
+ #
105
+ # 'writer_interests.interest_notes LIKE (?)'
106
+ #
107
+ # ORs
108
+ # ===
109
+ # You can combine two different fields into an OR on the same value by passing :fieldname=>[ "fieldname_1", "fieldname_2" ]
110
+ # e.g.
111
+ #
112
+ # Click => { :click_url_pattern=> {:operator=>"like", :field_name=>['request_path', 'http_referer']}}
113
+ #
114
+ # will generate:
115
+ #
116
+ # ['( clicks.request_path LIKE (?) OR clicks.http_referrer LIKE (?) )']
117
+ #
83
118
  def params_to_conditions( opts={} )
84
119
  require_param(opts, :params, :models)
85
120
 
@@ -96,7 +131,8 @@ module Trigga
96
131
 
97
132
  def model_conditions( opts, model_class, field_defs )
98
133
  h = {:where=>[], :values=>[]}
99
- field_defs.each{ |field_name, definition|
134
+
135
+ field_defs.each{ |field_name, definition|
100
136
  parsed_field_def = parse_field_definition( opts, model_class, field_name, definition )
101
137
  h[:where] += parsed_field_def[:where]
102
138
  h[:values] += parsed_field_def[:values]
@@ -108,12 +144,20 @@ module Trigga
108
144
  c = {:where=>[], :values=>[]}
109
145
  if opts[param_name]
110
146
  unless opts[param_name].to_s.empty?
111
- c[:where] << "( #{model_class.table_name}.#{definition[:field_name] || param_name.to_s} #{definition[:operator] || '='} (?) )"
147
+ ors = Array(definition[:field_name] || param_name.to_s).map{ |field| scoped_field_name( model_class, field ) + " " + (definition[:operator] || '=') + " (?)" }
148
+
149
+ clause = "( " + ors.join(' OR ') + " )"
150
+ # "( #{ scoped_field_name( model_class, (definition[:field_name] || param_name.to_s) ) } #{definition[:operator] || '='} (?) )"
151
+ c[:where] << clause
112
152
  c[:values] << ( definition[:operator] =~ /\blike\b/i ? opts[param_name].to_active_record_condition : opts[param_name] )
113
153
  end
114
154
  end
115
155
  c
116
156
  end
157
+
158
+ def scoped_field_name( model_class, field_name )
159
+ field_name.include?('.') ? field_name : "#{model_class.table_name}.#{field_name}"
160
+ end
117
161
  end
118
162
  end
119
163
  end
@@ -188,32 +188,72 @@ describe ::Trigga::ParamFu do
188
188
  @inside_the_brackets = Tester.parse_field_definition( @params, @model_class, @param_name, @definition )[:where][0].gsub(/^\s*\((.*)\)\s*$/, '\1')
189
189
  end
190
190
 
191
- it "should start with the model_class's table name as a scope" do
192
- @inside_the_brackets.should =~ /\s*model_class_table_name\..*/
191
+ it "should call scoped_field_name " do
192
+ Tester.should_receive(:scoped_field_name).and_return('blart')
193
+ Tester.parse_field_definition( @params, @model_class, @param_name, @definition )
193
194
  end
194
-
195
- context "When the definition has a :fieldname" do
196
- before(:each) do
197
- @definition[:field_name] = 'field_name'
198
- @inside_the_brackets = Tester.parse_field_definition( @params, @model_class, @param_name, @definition )[:where][0].gsub(/^\s*\((.*)\)\s*$/, '\1')
195
+
196
+ describe "scoped_field_name args" do
197
+ it "should start with the model class" do
198
+ Tester.should_receive(:scoped_field_name) do |args|
199
+ args[0].should == @model_class
200
+ 'blart'
201
+ end
202
+ Tester.parse_field_definition( @params, @model_class, @param_name, @definition )
199
203
  end
204
+
205
+ context "When the definition has a :fieldname" do
206
+ before(:each) do
207
+ @definition[:field_name] = 'field_name'
208
+ end
200
209
 
201
- it "should use the :fieldname" do
202
- @inside_the_brackets.should =~ /\s*[^\.]+\.field_name.*/
210
+ it "should pass the given :field_name as the second arg" do
211
+ Tester.should_receive(:scoped_field_name) do |args|
212
+ args[1].should == 'field_name'
213
+ 'blart'
214
+ end
215
+ Tester.parse_field_definition( @params, @model_class, @param_name, @definition )
216
+ end
203
217
  end
204
- end
205
-
206
- context "When the definition has no :fieldname" do
207
- before(:each) do
208
- @definition[:field_name] = nil
209
- @inside_the_brackets = Tester.parse_field_definition( @params, @model_class, @param_name, @definition )[:where][0].gsub(/^\s*\((.*)\)\s*$/, '\1')
218
+
219
+ context "When the definition has no :fieldname" do
220
+ before(:each) do
221
+ @definition[:field_name] = nil
222
+ end
223
+
224
+ it "should pass the given param_name converted to a string as the second arg" do
225
+ Tester.should_receive(:scoped_field_name) do |args|
226
+ args[1].should == 'param_1'
227
+ 'blart'
228
+ end
229
+ Tester.parse_field_definition( @params, @model_class, @param_name, @definition )
230
+ end
210
231
  end
232
+
233
+ context "when the definitions fieldname is an array" do
234
+ before(:each) do
235
+ @definition[:field_name] = ["field_name_1", "other_table.field_name_2"]
236
+ end
211
237
 
212
- it "should use the given param_name converted to a string as the field name" do
213
- @inside_the_brackets.should =~ /\s*[^\.]+\.param_1.*/
238
+ it "should call scoped_field_name with each element" do
239
+ Tester.should_receive(:scoped_field_name) do |args|
240
+ args[1].should == 'field_name_1'
241
+ 'blart'
242
+ end
243
+ Tester.should_receive(:scoped_field_name) do |args|
244
+ args[1].should == 'other_table.field_name_2'
245
+ 'blart'
246
+ end
247
+ Tester.parse_field_definition( @params, @model_class, @param_name, @definition )
248
+ end
249
+
250
+ it "should join the fieldname conditions together with OR" do
251
+ Tester.parse_field_definition( @params, @model_class, @param_name, @definition )[:where][0].should == "( model_class_table_name.field_name_1 = (?) OR other_table.field_name_2 = (?) )"
252
+ end
214
253
  end
254
+
215
255
  end
216
-
256
+
217
257
  context "When the definition has a :operator" do
218
258
  before(:each) do
219
259
  @definition[:operator] = 'my_operator'
@@ -275,6 +315,28 @@ describe ::Trigga::ParamFu do
275
315
  end
276
316
  end
277
317
 
318
+ describe "scoped_field_name" do
319
+ before do
320
+ @model_class = mock("model class")
321
+ @model_class.stub!(:table_name).and_return( 'model_class_table_name' )
322
+ end
323
+
324
+ context "when the given field_name contains a ." do
325
+ it "should just return the given field_name" do
326
+ Tester.scoped_field_name(@model_class, 'blart.flange').should == 'blart.flange'
327
+ end
328
+ end
329
+ context "when the given field_name does not contain a ." do
330
+ it "should call table_name on the model_class" do
331
+ @model_class.should_receive(:table_name).and_return( 'model_class_table_name' )
332
+ Tester.scoped_field_name(@model_class, 'blart')
333
+ end
334
+ it "should return the given field_name" do
335
+ Tester.scoped_field_name(@model_class, 'flange').should == 'model_class_table_name.flange'
336
+ end
337
+ end
338
+ end
339
+
278
340
  describe "model_conditions" do
279
341
  before(:each) do
280
342
  @params = { :param_1 => 'param_1 value' }
@@ -320,14 +382,15 @@ describe ::Trigga::ParamFu do
320
382
  end
321
383
 
322
384
  it "should pass each field_name" do
323
- Tester.should_receive(:parse_field_definition) do |args|
324
- args[2].should == :field_name_1
325
- @mock_parsed_field_def_1
326
- end
385
+
327
386
  Tester.should_receive(:parse_field_definition) do |args|
328
387
  args[2].should == :field_name_2
329
388
  @mock_parsed_field_def_2
330
389
  end
390
+ Tester.should_receive(:parse_field_definition) do |args|
391
+ args[2].should == :field_name_1
392
+ @mock_parsed_field_def_1
393
+ end
331
394
  Tester.model_conditions( @params, @model_class, @definitions )
332
395
  end
333
396
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: itrigga-param_fu
3
3
  version: !ruby/object:Gem::Version
4
- hash: 13
4
+ hash: 11
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 4
9
- - 1
10
- version: 0.4.1
9
+ - 2
10
+ version: 0.4.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Al Davidson
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-11-18 00:00:00 +00:00
19
+ date: 2011-12-02 00:00:00 +00:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency