Class: Edgarj::SearchForm

Inherits:
Search
  • Object
show all
Defined in:
app/models/edgarj/search_form.rb

Overview

‘SearchForm’ instance contains search-conditions entered at search-form as:

  1. search conditions (mainly string, but integers for timestamp) for eash attribute of model

  2. operator (=, <, >, …) for each attribute

  3. parent name for redraw

Model(ActiveRecord) intance itself (e.g. Customer.new) doesn’t satisfy to keep search condition because:

  1. id cannot be set because of protection.

  2. search condition may have operator (like ‘=’, ‘>=’)

This is why SearchForm class is created.

NOTE: model is stored in SearhForm as model_str.constantize to avoid following error:

ArgumentError (undefined class/module Customer)

Operator

Operator for some search-fields (e.g. integer, date) are initialized by params. For example, when search condition for Question screen GUI is:

Priority < 3

then, params is:

:priority=>3, :search_form_operator=>{:priority=>'<'}

and SearchForm object is built as:

s = SearchForm.new(Question, params[:search])

and finally it generates SQL condition as follows:

s.conditions      # ["priority<?", 3]

Parent name

In order to hold parent object ‘name’ value for redraw, _parent[] hash is used. It is passed from params.

BUGS

date-type(e.g. ‘created_at(1i)’=2010, ‘created_at(2i)’=2, …) and datetime-type are not supported now while jQuery datepicker is OK.

Defined Under Namespace

Modules: Dbms Classes: Operator

Constant Summary collapse

DEFAULT_TIMEZONE_FOR_TIMESTAMP_DATE_COMPARISON =
'9'

Instance Attribute Summary collapse

Attributes inherited from Search

#_klass_str, #errors

Instance Method Summary collapse

Methods inherited from Search

#persisted?

Constructor Details

#initialize(klass, attrs = {}) ⇒ SearchForm

Build SearchForm object from ActiveRecord ‘klass’ and attrs.

INPUTS

klass

ActiveRecord

attrs

hash of key=>value pair



103
104
105
106
107
108
109
# File 'app/models/edgarj/search_form.rb', line 103

def initialize(klass, attrs={})
  super(klass)
  @_table_name  = klass.table_name
  @attrs        = attrs.dup
  @_operator    = Operator.new(attrs[:edgarj_search_form_operator])
  @_parent      = attrs[:search_form_parent]
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args) ⇒ Object

map attribute name to hash entry. This mechanism is required to be used in ‘form_for’ helper.

When column type is integer and has digits value, return integer. This is required for selection helper. Even it is integer but has no value, keeps blank.

When attribute name ends ‘=’, assignment to hash works.

EXAMPLE

s = Searchform.new(Product, :name=>‘a’) s.name s.conditions # [“name=?”, “a”] s.name = ‘b’ # method_missing(‘name=’, ‘b’) is called s.conditions # [“name=?”, “b”]



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'app/models/edgarj/search_form.rb', line 127

def method_missing(method_name, *args)
  if method_name.to_s =~ /^(.*)=$/
    @attrs[$1.to_sym] = args[0]
  else
    val = @attrs[method_name.to_sym]
    case column_type(method_name)
    when :integer
      if val =~ /^\d+$/
        val.to_i
      else
        val
      end
    else
      val
    end
  end
end

Instance Attribute Details

#_operatorObject

Returns the value of attribute _operator.



47
48
49
# File 'app/models/edgarj/search_form.rb', line 47

def _operator
  @_operator
end

#_parentObject

Returns the value of attribute _parent.



47
48
49
# File 'app/models/edgarj/search_form.rb', line 47

def _parent
  @_parent
end

Instance Method Details

#conditionsObject

Generate search-conditions. Wildcard search by ‘*’ is supported on string attribute.

RETURN

condition_string, value_array

values for :conditions option on model



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'app/models/edgarj/search_form.rb', line 152

def conditions
  return ['1=0'] if !valid?

  conds       = []
  values      = []
  for col in klass.columns do
    col_str = col_name(col)
    val     = @attrs[encode_name(col)]
    if !val.blank?
      case col.type
      when :string, :text
        if val =~ /\*$/
          conds   << col_str + ' like ?'
          values  << val.gsub(/\*$/, '%')
        else
          conds   << col_str + '=?'
          values  << val
        end
      when :datetime
        case is_dbms?
        when Dbms::MYSQL
#             conds   << col_str + @_operator.exp(encode_name(col))
          conds   << sprintf("date(%s)",
              col_str) +
              @_operator.exp(encode_name(col))
        else
          conds   << sprintf("date(timezone('%s',%s))",
              DEFAULT_TIMEZONE_FOR_TIMESTAMP_DATE_COMPARISON,
              col_str) +
              @_operator.exp(encode_name(col))
        end
        values  << val.to_s
      when :boolean
        case is_dbms?
        when Dbms::MYSQL
          conds   << col_str + @_operator.exp(encode_name(col))
          values  << (val=='true')
        else
          conds   << col_str + @_operator.exp(encode_name(col))
          values  << val
        end
      else
        conds   << col_str + @_operator.exp(encode_name(col))
        values  << val
      end
    end
  end
  return [conds.join(' and ')] + values
end

#klassObject



202
203
204
# File 'app/models/edgarj/search_form.rb', line 202

def klass
  @_klass_str.constantize
end