Module: Trigga::ParamFu::AllMethods

Defined in:
lib/trigga/param_fu/param_fu.rb

Instance Method Summary collapse

Instance Method Details

#id_or_name_condition(table, val) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/trigga/param_fu/param_fu.rb', line 39

def id_or_name_condition(table, val)
  condition = {:where => nil, :values=>nil}
  unless val.to_s.empty?
    unless val.to_s.match(/[^0-9]/)
      condition[:where] = "#{table}.id = ?"
      condition[:values] = val.to_i
    else
      condition[:where] = "#{table}.name LIKE ?"
      condition[:values] = "#{'%' + val.gsub(/\s*\(\d+\)/,"")  + '%'}"
    end
  end
  condition
end

#key_with_id(key) ⇒ Object



29
30
31
# File 'lib/trigga/param_fu/param_fu.rb', line 29

def key_with_id(key)
  (key.to_s + '_id').to_sym
end

#model_conditions(opts, model_class, field_defs) ⇒ Object



132
133
134
135
136
137
138
139
140
141
# File 'lib/trigga/param_fu/param_fu.rb', line 132

def model_conditions( opts, model_class, field_defs )
  h = {:where=>[], :values=>[]}

  field_defs.each{ |field_name, definition|          
    parsed_field_def = parse_field_definition( opts, model_class, field_name, definition )
    h[:where] += parsed_field_def[:where]
    h[:values] += parsed_field_def[:values]
  }
  h
end

#obj_or_id(opts, key) ⇒ Object



25
26
27
# File 'lib/trigga/param_fu/param_fu.rb', line 25

def obj_or_id(opts, key)
  opts[key_with_id(key)] ||= opts[key].id if opts[key]
end

#params_to_conditions(opts = {}) ⇒ Object

Give this a hash per model in the format:

Model class => { param_name => { :operator=>(db operator - defaults to ‘=’),

> :field_name=>(field_name in the database - defaults to param_name)

> }

> }

and it will return an ActiveRecord finder :conditions clause using any params which are present in the given :params e.g. if you have params = { :created_date_from=>‘2011-10-09 00:01:02’, :status=>‘A’, :click_url=>‘items.html’ } then calling:

params_to_conditions( :params=>params, :models=>{

Click => {:click_url=>{ :operator=>"like", :field_name=>'request_path' }, 
          :status => {},
          :http_referer=>{:operator=>'like'},
          :created_date_from => {:operator=> ">=", :field_name=>'timestamp'}
          }

})

will generate:

‘clicks.request_path like (?) AND clicks.status = ? AND clicks.created_date_from >= ?’, ‘%items.html%’, ‘A’, ‘2011-10-09 00:01:02’

It will ignore any criteria given which are NOT in the given :params hash

Table Names

By default each field given in a model class key is automatically scoped by the table name - e.g.

Person => { :status=>{} }

results in a where clause of

‘people.status = (?)’

Sometimes you need to scope a field by another table name - e.g. when you have a joined table, or an aliased table If your fieldname contains a dot (‘.’) it will NOT be scoped by the table name, it will be left as given

e.g.

Writer => { :interested_in => { :operator => ‘LIKE’, :field_name=> }}

gives

‘writer_interests.interest_notes LIKE (?)’

ORs

You can combine two different fields into an OR on the same value by passing :fieldname=>[ “fieldname_1”, “fieldname_2” ] e.g.

Click => { :click_url_pattern=> :field_name=>[‘request_path’, ‘http_referer’]}

will generate:

‘( clicks.request_path LIKE (?) OR clicks.http_referrer LIKE (?) )’


118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/trigga/param_fu/param_fu.rb', line 118

def params_to_conditions( opts={} )
  require_param(opts, :params, :models) 
  
  conds = { :where=>[], :values=>[] }

  opts[:models].each { |model_class, field_defs|
    parsed_model_conditions = model_conditions( opts[:params], model_class, field_defs )
    conds[:where]  += parsed_model_conditions[:where]
    conds[:values] += parsed_model_conditions[:values]
  }
 
  [ conds[:where].join(" AND ") ] + conds[:values]
end

#parse_field_definition(opts, model_class, param_name, definition) ⇒ Object



143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/trigga/param_fu/param_fu.rb', line 143

def parse_field_definition( opts, model_class, param_name, definition )
  c = {:where=>[], :values=>[]}
  if opts[param_name] 
    unless opts[param_name].to_s.empty?
      ors = Array(definition[:field_name] || param_name.to_s).map{ |field|  scoped_field_name( model_class, field ) + " " + (definition[:operator] || '=') + " (?)" }
      
      clause = "( " + ors.join(' OR ') + " )"
#             "( #{ scoped_field_name( model_class, (definition[:field_name] || param_name.to_s) ) } #{definition[:operator] || '='} (?) )" 
      c[:where] << clause
      ors.size.times{ |i| c[:values] << ( definition[:operator] =~ /\blike\b/i ? opts[param_name].to_active_record_condition : opts[param_name] ) }
    end
  end
  c
end

#require_obj_or_id(opts, key) ⇒ Object

Raises:

  • (ArgumentError)


12
13
14
15
16
# File 'lib/trigga/param_fu/param_fu.rb', line 12

def require_obj_or_id(opts, key)
  obj_or_id(opts,key)
  raise ArgumentError.new("#{key} or #{key_with_id(key)} are required") unless opts[key_with_id(key)]
  opts
end

#require_one_of(opts, *keys) ⇒ Object

Raises:

  • (ArgumentError)


33
34
35
36
37
# File 'lib/trigga/param_fu/param_fu.rb', line 33

def require_one_of( opts, *keys )
  present = (opts.keys & keys)
  raise ArgumentError.new( "at least one of the arguments #{keys.inspect} is required" ) if present.empty?
  return present
end

#require_param(opts, *keys) ⇒ Object



18
19
20
21
22
23
# File 'lib/trigga/param_fu/param_fu.rb', line 18

def require_param(opts, *keys)
  keys.to_a.each do |k|
    raise ArgumentError.new("#{k} is required") unless opts[k]
  end
  opts
end

#scoped_field_name(model_class, field_name) ⇒ Object



158
159
160
# File 'lib/trigga/param_fu/param_fu.rb', line 158

def scoped_field_name( model_class, field_name )
  field_name.include?('.') ? field_name : "#{model_class.table_name}.#{field_name}"
end

#to_plural(s) ⇒ Object

fallback when we don’t have ActiveSupport’s pluralize method available



55
56
57
# File 'lib/trigga/param_fu/param_fu.rb', line 55

def to_plural(s)
  (s.match(/[aeiou]$/i) ? s + 's' : s + 'es' )
end