meta_search 0.5.1 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG CHANGED
@@ -1,3 +1,8 @@
1
+ Changes since 0.5.1 (2010-07-20):
2
+ * Fix fallback for failed cast via to_time or to_date
3
+ * add :cast option for custom Wheres, allowing a where to override
4
+ the default cast of the incoming parameters.
5
+
1
6
  Changes since 0.5.0 (2010-06-08):
2
7
  * Fix searching against relations derived from a has_many :through
3
8
  association
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.1
1
+ 0.5.2
@@ -234,8 +234,8 @@ module MetaSearch
234
234
  end
235
235
 
236
236
  define_method("#{attribute}_#{predicate}=") do |val|
237
- search_attributes["#{attribute}_#{predicate}"] = cast_attributes(column_type(attribute), val)
238
237
  where = Where.new(predicate)
238
+ search_attributes["#{attribute}_#{predicate}"] = cast_attributes(where.cast || column_type(attribute), val)
239
239
  if where.validate(search_attributes["#{attribute}_#{predicate}"])
240
240
  arel_attribute = get_attribute(attribute)
241
241
  @relation = where.eval(@relation, arel_attribute, search_attributes["#{attribute}_#{predicate}"])
@@ -3,15 +3,15 @@ require 'meta_search/exceptions'
3
3
  module MetaSearch
4
4
  module Utility #:nodoc:
5
5
  private
6
-
6
+
7
7
  def array_of_arrays?(vals)
8
8
  vals.is_a?(Array) && vals.first.is_a?(Array)
9
9
  end
10
-
10
+
11
11
  def array_of_dates?(vals)
12
12
  vals.is_a?(Array) && vals.first.respond_to?(:to_time)
13
13
  end
14
-
14
+
15
15
  def cast_attributes(type, vals)
16
16
  if array_of_arrays?(vals)
17
17
  vals.map! {|v| cast_attributes(type, v)}
@@ -29,7 +29,7 @@ module MetaSearch
29
29
  val.respond_to?(:to_s) ? val.to_s : String.new(val)
30
30
  when *DATES
31
31
  if val.respond_to?(:to_date)
32
- val.to_date
32
+ val.to_date rescue nil
33
33
  else
34
34
  y, m, d = *[val].flatten
35
35
  m ||= 1
@@ -38,7 +38,7 @@ module MetaSearch
38
38
  end
39
39
  when *TIMES
40
40
  if val.respond_to?(:to_time)
41
- val.to_time
41
+ val.to_time rescue nil
42
42
  else
43
43
  y, m, d, hh, mm, ss = *[val].flatten
44
44
  Time.zone.local(y, m, d, hh, mm, ss) rescue nil
@@ -55,7 +55,7 @@ module MetaSearch
55
55
  raise TypeCastError, "Unable to cast columns of type #{type}"
56
56
  end
57
57
  end
58
-
58
+
59
59
  def collapse_multiparameter_options(opts)
60
60
  opts.keys.each do |k|
61
61
  if k.include?("(")
@@ -73,11 +73,11 @@ module MetaSearch
73
73
  end
74
74
  opts
75
75
  end
76
-
76
+
77
77
  def quote_table_name(name)
78
78
  ActiveRecord::Base.connection.quote_table_name(name)
79
79
  end
80
-
80
+
81
81
  def quote_column_name(name)
82
82
  ActiveRecord::Base.connection.quote_column_name(name)
83
83
  end
@@ -52,7 +52,7 @@ module MetaSearch
52
52
  #
53
53
  # will match articles authored by Jimmy, Bobby, or Freddy, but not Winifred.
54
54
  class Where
55
- attr_reader :name, :aliases, :types, :predicate, :formatter, :validator
55
+ attr_reader :name, :aliases, :types, :cast, :predicate, :formatter, :validator
56
56
  def initialize(where)
57
57
  if [String,Symbol].include?(where.class)
58
58
  where = Where.get(where) or raise ArgumentError("A where could not be instantiated for the argument #{where}")
@@ -60,26 +60,27 @@ module MetaSearch
60
60
  @name = where[:name]
61
61
  @aliases = where[:aliases]
62
62
  @types = where[:types]
63
+ @cast = where[:cast]
63
64
  @predicate = where[:predicate]
64
65
  @validator = where[:validator]
65
66
  @formatter = where[:formatter]
66
67
  @splat_param = where[:splat_param]
67
68
  end
68
-
69
+
69
70
  def splat_param?
70
71
  !!@splat_param
71
72
  end
72
-
73
+
73
74
  # Format a parameter for searching using the Where's defined formatter.
74
75
  def format_param(param)
75
76
  formatter.call(param)
76
77
  end
77
-
78
+
78
79
  # Validate the parameter for use in a search using the Where's defined validator.
79
80
  def validate(param)
80
81
  validator.call(param)
81
82
  end
82
-
83
+
83
84
  # Evaluate the Where for the given relation, attribute, and parameter(s)
84
85
  def eval(relation, attribute, param)
85
86
  if splat_param?
@@ -88,19 +89,19 @@ module MetaSearch
88
89
  relation.where(attribute.send(predicate, format_param(param)))
89
90
  end
90
91
  end
91
-
92
+
92
93
  class << self
93
94
  # At application initialization, you can add additional custom Wheres to the mix.
94
95
  # in your application's <tt>config/initializers/meta_search.rb</tt>, place lines
95
96
  # like this:
96
97
  #
97
- # MetaSearch::Where.add :between, :btw,
98
- # :predicate => :in,
99
- # :types => [:integer, :float, :decimal, :date, :datetime, :timestamp, :time],
100
- # :formatter => Proc.new {|param| Range.new(param.first, param.last)},
101
- # :validator => Proc.new {|param|
102
- # param.is_a?(Array) && !(param[0].blank? || param[1].blank?)
103
- # }
98
+ # MetaSearch::Where.add :between, :btw,
99
+ # :predicate => :in,
100
+ # :types => [:integer, :float, :decimal, :date, :datetime, :timestamp, :time],
101
+ # :formatter => Proc.new {|param| Range.new(param.first, param.last)},
102
+ # :validator => Proc.new {|param|
103
+ # param.is_a?(Array) && !(param[0].blank? || param[1].blank?)
104
+ # }
104
105
  #
105
106
  # The first options are all names for the where. Well, the first is a name, the rest
106
107
  # are aliases, really. They will determine the suffix you will use to access your Where.
@@ -133,16 +134,33 @@ module MetaSearch
133
134
  # to be splatted (converted to an argument list). This is not normally useful and defaults to
134
135
  # false, but is used when automatically creating compound Wheres (*_any, *_all) so that the
135
136
  # Arel attribute method gets the correct parameter list.
137
+ #
138
+ # <tt>cast</tt> will override the normal cast of the parameter when using this Where
139
+ # condition. Normally, the value supplied to a condition is cast to the type of the column
140
+ # it's being compared against. In cases where this isn't desirable, because the value you
141
+ # intend to accept isn't the same kind of data you'll be comparing against, you can override
142
+ # that cast here. For example, this is a Where that you can use with a check_box to allow
143
+ # searching for records with a blank column. It's important to always cast to integer here,
144
+ # as otherwise the default checked check_box value, "1", would cast to an invalid date when
145
+ # searching against date columns, and fall back to nil, making your check_box do nothing:
146
+ #
147
+ # MetaSearch::Where.add :is_blank,
148
+ # :predicate => :in,
149
+ # :cast => :integer,
150
+ # :formatter => Proc.new {|param| [nil, '']},
151
+ # :validator => Proc.new {|param|
152
+ # !param.zero?
153
+ # }
136
154
  def add(*args)
137
155
  where = create_where_from_args(*args)
138
156
  create_where_compounds_for(where)
139
157
  end
140
-
158
+
141
159
  # Returns the complete array of Wheres
142
160
  def all
143
161
  @@wheres
144
162
  end
145
-
163
+
146
164
  # Get the where matching a method or predicate.
147
165
  def get(method_id_or_predicate)
148
166
  return nil unless where_key = @@wheres.keys.
@@ -152,7 +170,7 @@ module MetaSearch
152
170
  where = @@wheres[where] if where.is_a?(String)
153
171
  where
154
172
  end
155
-
173
+
156
174
  # Set the wheres to their default values, removing any customized settings.
157
175
  def initialize_wheres
158
176
  @@wheres = {}
@@ -160,9 +178,9 @@ module MetaSearch
160
178
  add(*where)
161
179
  end
162
180
  end
163
-
181
+
164
182
  private
165
-
183
+
166
184
  # "Creates" the Where by adding it (and its aliases) to the current hash of wheres. It then
167
185
  # instantiates a Where and returns it for use.
168
186
  def create_where_from_args(*args)
@@ -172,6 +190,7 @@ module MetaSearch
172
190
  opts[:name] ||= args.first
173
191
  opts[:types] ||= ALL_TYPES
174
192
  opts[:types] = [opts[:types]].flatten
193
+ opts[:cast] = opts[:cast]
175
194
  opts[:predicate] ||= :eq
176
195
  opts[:splat_param] ||= false
177
196
  opts[:formatter] ||= Proc.new {|param| param}
@@ -201,7 +220,7 @@ module MetaSearch
201
220
  end
202
221
  new(opts[:name])
203
222
  end
204
-
223
+
205
224
  # Takes the provided +where+ param and derives two additional Wheres from it, with the
206
225
  # name appended by _any/_all. These will use Arel's grouped predicate methods (matching
207
226
  # the same naming convention) to be invoked instead, with a list of possible/required
@@ -227,6 +246,6 @@ module MetaSearch
227
246
  end
228
247
  end
229
248
  end
230
-
249
+
231
250
  Where.initialize_wheres
232
251
  end
data/meta_search.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{meta_search}
8
- s.version = "0.5.1"
8
+ s.version = "0.5.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Ernie Miller"]
12
- s.date = %q{2010-07-20}
12
+ s.date = %q{2010-07-22}
13
13
  s.description = %q{
14
14
  Allows simple search forms to be created against an AR3 model
15
15
  and its associations, has useful view helpers for sort links
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 5
8
- - 1
9
- version: 0.5.1
8
+ - 2
9
+ version: 0.5.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Ernie Miller
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-07-20 00:00:00 -04:00
17
+ date: 2010-07-22 00:00:00 -04:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency