binarylogic-searchlogic 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,321 @@
1
+ == 2.0.1
2
+
3
+ * Allow the chaining of conditions off of a search object. Ex: search.username_like("bjohnson").age_gt(20).all
4
+ * Split out left outer join creation into its own method, allowing you to use it in your own named scopes.
5
+ * Make sure the search objects clone properly.
6
+ * named_scope_options should return the proper options for existing named scopes with an arity greater than 0
7
+
8
+ == 2.0.0
9
+
10
+ * Everything, completely rewritten.
11
+
12
+ == 1.6.6
13
+
14
+ * Fixed time zone issues when searching.
15
+
16
+ == 1.6.5 released 2009-04-2
17
+
18
+ * Skip all associations defined with the :finder_sql option, since conditions can not be chained to them, etc.
19
+ * Fixed bug when using non string values for the keywords condition.
20
+ * Fixed undefined methods link_options error.
21
+ * Return blank conditions when trying to scope blank conditions. Fixes the issue with groups that return a blank SQL string.
22
+ * Fixed issue with blank condition comparing boolean values to non boolean columns.
23
+ * Add utf-8 magic comment for ruby 1.9
24
+
25
+ == 1.6.4 released 2009-01-22
26
+
27
+ * Fixed calling attribute_condition with newer versions of rails.
28
+
29
+ == 1.6.3 released 2008-12-13
30
+
31
+ * Added in avg, count, and sum modifiers for SQLite and Postgres.
32
+ * Added ne for not_equal condition.
33
+ * Ignore :include option for calculations since we don't need it and AR throws an error for polymorphic relationships.
34
+ * Removed sum and count since they can not be in the WHERE statement, but must be in the HAVING statement
35
+ * Added in auto joins for groups so that the joins don't have to be manually specified.
36
+ * Use first column in column_names as the default column for calculations, since a column is required when using DISTINCT and some tables can have more than one primary key.
37
+ * On associations see what the first conditions "any" status is to determine if to join with "ANY" or "AND"
38
+
39
+ == 1.6.2 released 2008-12-13
40
+
41
+ * Remove duplicate joins at a lower level for a cleaner and less brittle approach.
42
+
43
+ == 1.6.1 released 2008-12-8
44
+
45
+ * Group multi faceted conditions since we allow for the mix of "and" and "or"
46
+ * Blank arrays are not meaningful values for conditions
47
+ * Add in a unique identifier for the auto-generated hidden fields so that multiple forms do no present a problem.
48
+
49
+ == 1.6.0 released 2008-12-8
50
+
51
+ * Converted all tree conditions to nested set conditions for performance reasons. A nested set data structure is now required instead of a tree
52
+ * Added DISTINCT to select if you are not provided a select, searching, and have joins.
53
+ * Included :not_like in the list of conditions to be required upon initialization.
54
+
55
+ == 1.5.10 released 2008-12-8
56
+
57
+ * Create class level conditions upon instantiation to avoid conflicts.
58
+
59
+ == 1.5.9 released 2008-12-3
60
+
61
+ * Added metaclass object extension for older version of ActiveSupport.
62
+ * Added average, count, and sum modifiers.
63
+
64
+ == 1.5.8 released 2008-12-3
65
+
66
+ * Removed array support for groups, arrays will set conditions, not create multiple groups. If you need to create multiple groups you will have to pass an array with multiple {:group => my_groups} hashes.
67
+ * Fixed issues with using name spaced models.
68
+ * Added support for multiparameter conditions to support date_select helpers.
69
+
70
+ == 1.5.7 released 2008-11-30
71
+
72
+ * Fixed how grouping works, you can now specify "and_group" and "or_group", just like you can with conditions.
73
+ * Specifying a join type will take priority. So "and_name_like" will ALWAYS join with AND, even is any = true for the search.
74
+
75
+ == 1.5.6 released 2008-11-29
76
+
77
+ * The order conditions are set is now relevant and will be reflected in the SQL. Setting a condition first will make it first in the SQL, setting a condition last will make it last in the SQL.
78
+ * The above allows for prefixing any condition with and_ or or_. Thus letting you create somewhat more complex queries, since the order matters.
79
+ * Added ability to group conditions to mimic parenthesis in raw SQL.
80
+ * Major clean up in the Searchlogic::Conditions name space: faster, smaller, cleaner, and modular.
81
+
82
+ == 1.5.5 released 2008-11-17
83
+
84
+ * Cleaned up class_name configuration for helpers, so that setting them to nil disables the class name
85
+ * Added page_links_div_wrapper and page_links_div_wrapper_class_name configuration option to add an wrapping div around page_links
86
+ * Added page_links_act_like_will_paginate configuration option to help with the transition from will_paginate
87
+
88
+ == 1.5.4 released 2008-11-16
89
+
90
+ * Removed subclass requirement for adding conditions in Conditions::Base
91
+ * Removed DISTINCT in the select clause, instead called uniq! on the results. PostgreSQL complains about DISTINCT and AR uses uniq! when using :includes, so this is the best option.
92
+ * Converted the return for SQLite's strftime to integer from string. This way day of month, day of year, etc works as expected.
93
+
94
+ == 1.5.3 released 2008-10-30
95
+
96
+ * Removed ilike conditions and let the like condition determine if it should use like or ilike depending on the connection adapter.
97
+ * Fixed bug where the keywords condition was removing foreign characters.
98
+ * Added configuration option for specifying your javascript library, to cut down on the javascript Searchlogic adds into the form helpers
99
+ * Fixed bug with "not" conditions to use sanitize method, like it should, instead of to_conditions.
100
+ * Only pass :distinct option for the count calculation
101
+ * Fixed not_nil and not_blank conditions to use boolean values configuration option.
102
+
103
+ == 1.5.2 released 2008-10-21
104
+
105
+ * Added ilike conditions
106
+ * Removed configatron dependency (was accidentally added)
107
+
108
+ == 1.5.1 released 2008-10-20
109
+
110
+ * Fixed bug with per_page_links
111
+ * Added "ordering_by" class for per_page_links
112
+
113
+ == 1.5.0 released 2008-10-20
114
+
115
+ * Merge array of conditions with or or and where it makes sense. Begins with condition does not make sense to join with and, so instead join with or.
116
+ * Cleaned up html validity so it will pass W3C validators
117
+ * Restructure configuration to be more organized and allow for more configuration options.
118
+ * Added more configuration options, especially for class names.
119
+
120
+ == 1.4.1 released 2008-10-15
121
+
122
+ * Extracted english text into configuration to support alternate languages. I18n support.
123
+ * Improved method detection in add_joins to use respond_to? with the private method option set to true
124
+
125
+ == 1.4.0 released 2008-10-15
126
+
127
+ * Fixed bug when duping or cloning to copy over instance vars instead of method values
128
+ * Fixed bug with older versions of ActiveRecord and creating an alias method chain on find in AssociationCollection
129
+ * Added modifiers: upper, lower, trim, ltrim, rtrim
130
+ * Added not_nil and not_blank conditions
131
+ * Modified conditions so that table name is a variable, this allows table name to be switched on the fly.
132
+ * Modified auto joins to return symbols instead of SQL. This allows AR to properly merge the joins and ultimately result in proper SQL when performing multiple complex scopes.
133
+ * Fixed conflicts between includes and joins, duplicate joins are not added. Includes are prioritized. This also makes ActiveRecord much more flexible. Now you can cherry pick included associations. And not have to worry about conflicting with joins.
134
+ * Modified ActiveRecord's default behavior to use inner joins with the :joins option. Inner joins impose limitations. When providing this as a "convenience", inner joins do not make sense. The don't allow OR conditions to be across associations, nor does it properly order when an ordering by an association attribute when that association is optional.
135
+
136
+ == 1.3.5 released 2008-10-08
137
+
138
+ * Since joins are now strings, AR doesn't know how to merge them properly. So searchlogic now checks which joins to skip over to avoid conflicts.
139
+
140
+ == 1.3.4 released 2008-10-07
141
+
142
+ * Fixed method names creation for conditions with modifiers
143
+ * Create local column conditions, incase there are method conflicts. Such as "id".
144
+ * All joins are switched to left outer joins. When search with *any* conditions, inner joins return incorrect results. Also when ordering by an association that allows for blanks, inner joins exclude the records with blank values. Only option is left outer joins.
145
+ * If joins is manually set with a string, treat it as SQL, just like ActiveRecord
146
+
147
+ == 1.3.3 released 2008-10-03
148
+
149
+ * Fixed modifiers being double escaped on equals condition
150
+ * Fixed bug when merging conditions with array substitutions
151
+ * Updated blank condition to check if the values is false or not
152
+ * Fixed type for the year modifier in the mysql adapter
153
+
154
+ == 1.3.2 released 2008-10-03
155
+
156
+ * Fixed condition to type cast all values in an array
157
+ * Fixed bug to properly set the type for the type cast column
158
+ * Fixed bug to allow conditions on local columns
159
+ * Apparently ActiveRecord 2.2 doesnt remove duplicates on all joins, need to enforce this for ALL versions of ActiveRecord
160
+ * Fixed bug when passing a symbol as the SQL type for condition return types
161
+ * Moved duplicate removal to only apply when searching or calculating from a search object. Anything done in a normal ActiveRecord method should remain untouched and let ActiveRecord handle it. Just like in ActiveRecord if you do a User.all search and pass some :joins, you might get duplicate records. Searchlogic should not change that behavior, unless called from a searchlogic object.
162
+ * Discard meaningless array values when setting a condition.
163
+ * Delete blank strings from mass assignments on conditions.
164
+
165
+ == 1.3.1 released 2008-10-02
166
+
167
+ * Fixed bug when requiring a connection adapter that is not present
168
+ * Fixes bug in "not" conditions
169
+
170
+ == 1.3.0 released 2008-10-02
171
+
172
+ * Added modifiers into the mix: hour_of_created_at_less_than = 10, etc.
173
+ * Changed how the Searchlogic::Conditions::Base class works. Instead of predefining all methods for all conditions upon instantiation, they are defined as needed via method_missing. Similar to
174
+ ActiveRecord's dynamic finders: User.find_by_name_and_email(name, email). Once the are defined they never hit method_missing again, acts like a cache.
175
+ * Altered how values are handled for each condition, meaningless values are ignored completely.
176
+ * Added in more "not" conditions: not_like, not_begin_with, not_have_keywords, etc
177
+
178
+ == 1.2.2 released 2008-09-29
179
+
180
+ * Fixed bug when reverse engineering order to order_by, assumed ASC and DESC would always be present when they are not.
181
+ * False is a meaningful value for some conditions, and false.blank? == true. So instead of using value.blank? to ignore conditions we use meaningless?(value), which returns false if it is false.
182
+ * Fixed aliases for lt, lte, gt, and gte.
183
+ * Fixed bug when writing conditions on associations via a hash with string keys
184
+ * Added Config.remove_duplicates to turn off the "automatic" removing of duplicates if desired.
185
+ * Updated searchlogic_state helper to insert the entire state all at once.
186
+ * Added CSS class "ordering" to order_by_link if the search is being ordered by that.
187
+
188
+ == 1.2.1 released 2008-09-25
189
+
190
+ * Fixed problem when determining if an order_by_link is currently being ordered. Just "stringified" both comparable values.
191
+ * Removed default order_by and order_as. They will ONLY have values if you specify how to order, otherwise they are nil.
192
+ * Removed order_as requirement. order_as is optional.
193
+ * Added in deep_merge methods for hash, copied over from ActiveSupport 2.1
194
+ * Improved order by auto joins to be based off of what order_by returns instead of setting it when setting order_by.
195
+ * Added priority_order_by. Useful if you want to order featured products first and then order as usual. See documentation in Searchlogic::Search::Ordering for more info.
196
+ * Added in base64 support for order_by and priority_order_by so that it's value is safe in the URL
197
+ * Added priority_order_by_link
198
+
199
+ == 1.2.0 released 2008-09-24
200
+
201
+ * Added searchlogic_params and searchlogic_url helper to use outside of the control type helpers.
202
+ * Added dup and clone methods that work properly for searchlogic objects
203
+ * Fixed bug to remove nil scope values, HABTM likes to add :limit => nil
204
+ * Removed unnecessary build_search methods for associations
205
+ * Removed support for searching with conditions only. This just made things much more complicated when you can accomplish the same thing by starting a new search and only setting conditions.
206
+ * Fixed bug when searching with *any* conditions to use left outer joins instead of inner joins.
207
+
208
+ == 1.1.3 released 2008-09-23
209
+
210
+ * Setting a condition to nil removes it if the condition is set to ignore blanks
211
+ * Setting search.conditions = "some sql" will reset ALL conditions. Alternatively search.conditions => {:first_name_contains => "Ben"} will overwrite "some sql". The same goes with search.conditions.first_name_contains = "Ben".
212
+ * Fixed bug with inspect
213
+ * Other small performance enhancements with memoized attributes
214
+
215
+ == 1.1.2 released 2008-09-22
216
+
217
+ * Fixed bug with select control types not using :search_obj to determine its select values.
218
+ * Added is_nil and is_blank condition types.
219
+ * "memoized" various attributes for performance enhancements
220
+ * Removed the :order option from calculation options when :order is useless and just slows down query.
221
+ * Switched from using :include to :joins, big performance increase
222
+
223
+ == 1.1.1 released 2008-09-19
224
+
225
+ * Fixed typo in "next page" button.
226
+ * Updated valid options for searching and performing calculations, fixed some bugs when searching and performing calculations with advanced options.
227
+ * Fixed bug in ordering where table name was assumed by the hash. Now assumed by the reflection.
228
+ * Added default for per_page, so pagination comes implemented by default
229
+ * On mass assignments blank strings for *any* conditions are ignored. Sometimes blank strings are meaningful for "equals" and "does not equal", those only takes effect if you explicitly call these conditions: search.conditions.name = "". User.new_search(:conditions => {:name => ""}) will be ignored. Also, Searchlogic should never change how ActiveRecord behaves by default. So User.all(:conditions => {:name => ""}) will NOT be ignored.
230
+
231
+ == 1.1.0 released 2008-09-18
232
+
233
+ * Added the options :inner_spread and :outer_spread to the page_links helper. Also added various config options for setting page_links defaults.
234
+ * Updated calculation methods to ignore :limit and :offset. AR returns 0 or nil on calculations that provide an offset.
235
+ * Added support to allow for "any" of the conditions, instead of all of them. Joins conditions with "or" instead of "and". See Searchlogic::Conditions::Base or the readme
236
+
237
+ == 1.0.4 released 2008-09-18
238
+
239
+ * Fixed bugs when performing calculations and searches on has_many through relationships.
240
+ * Instead of merging the find_options myself, I delegated that to AR's with_scope function, which already does this. Much more solid, less intrusive.
241
+
242
+ == 1.0.3 released 2008-09-18
243
+
244
+ * Updated inspect to show the current options for your search. Plays nicer in the console.
245
+ * Made sure protection state is persistent among relationship conditions.
246
+ * Fixed bug with backwards compatibility of rails. concat requires a proc in older version.
247
+ * Defaulted remote control types to use GET requests instead of POST.
248
+ * Completely reengineered integration with ActiveRecord. Searchlogic is properly using scopes letting you do use serachgasm where scope are implemented. @current_users.orders.new_search, etc. If your search is scoped and you want a search object, that search object will represent a new search in the context of those scopes, meaning the scopes get merged into Searchlogic as options.
249
+ * Dropped support for Searchlogic functionality when defining relationships: has_many :order, :conditions => {:total_gt => 100}, will not work anymore. It's a chicken and the egg thing. Searchlogic needs AR constants, some models get loaded before others, therefore the Order model may not have been loaded yet, causing an unknown constant error.
250
+ * Clean up redundant code and moved it into the Searchlogic::Shared namespace.
251
+
252
+ == 1.0.2 released 2008-09-12
253
+
254
+ * Moved cached searchers out of the global namespace and into the Searchlogic::Cache namespce.
255
+ * Various changes to improve performance through profiling / benchmarking. http://pastie.org/271936
256
+ * Config.per_page works with new_search & new_search! only. Where as before it was only working if the search was protected.
257
+
258
+ == 1.0.1 released 2008-09-11
259
+
260
+ * Cached "searchers" so when a new search object is instantiated it doesn't go through all of the meta programming and method creation. Helps a lot with performance. You will see the speed benefits after the first instantiation.
261
+ * Added in new options for page_links.
262
+ * Fixed minor bugs when doing page_links.
263
+ * Updated documentation to be more detailed and inclusive.
264
+
265
+ == 1.0.0 released 2008-09-08
266
+
267
+ * Major changes in the helpers, they were completely re-engineered. Hence the new version. I established a pattern between all helpers giving you complete flexibility as to how they are used. All helpers are called differently now (see documentation).
268
+
269
+ == 0.9.10 released 2008-09-08
270
+
271
+ * Fixed bug with setting the per_page configuration to only take effect on protected searches, thus staying out of the way of normal searching.
272
+ * Hardened more tests
273
+
274
+ == 0.9.9 released 2008-09-07
275
+
276
+ * Fixed setting per_page to nil, false, or ''. This is done to "show all" results.
277
+
278
+ == 0.9.8 released 2008-09-06
279
+
280
+ * Fixed order_by helper bug when guessing the text with arrays. Should use the first value instead of last.
281
+ * Added in per_page config option.
282
+
283
+ == 0.9.7 released 2008-09-06
284
+
285
+ * Complete class restructure. Moved the 3 main components into their own base level class: Search, Conditions, Condition
286
+ * Split logic and functionality into their own modules, implemented via alias_chain_method
287
+ * Added in helpers for using in a rails app
288
+ * Added link to documentation and live example in README
289
+ * Various small bug fixes
290
+ * Hardened tests
291
+
292
+ == 0.9.6 released 2008-09-04
293
+
294
+ * Fixed bug when instantiating with nil options
295
+
296
+ == 0.9.5 released 2008-09-03
297
+
298
+ * Enhanced searching with conditions only, added in search methods and calculations
299
+ * Updated README to include examples
300
+
301
+ == 0.9.4 released 2008-09-03
302
+
303
+ * Cleaned up search methods
304
+ * Removed reset! method for both searching and searching by conditions
305
+
306
+ == 0.9.3 released 2008-09-02
307
+
308
+ * Changed structure of conditions to have their own class
309
+ * Added API for adding your own conditions.
310
+
311
+ == 0.9.2 released 2008-09-02
312
+
313
+ * Enhanced protection from SQL injections (made more efficient)
314
+
315
+ == 0.9.1 released 2008-09-02
316
+
317
+ * Added aliases for datetime, date, time, and timestamp attrs. You could call created_at_after, now you can also call created_after. Just removed the "at" requirement.
318
+
319
+ == 0.9.0 released 2008-09-01
320
+
321
+ * First release
data/README.rdoc CHANGED
@@ -1,10 +1,10 @@
1
1
  = Searchlogic
2
2
 
3
- <b>Searchlogic has been <em>completely</em> rewritten for v2. It is much simpler and has taken an entirely new approach. To give you an idea, v1 had ~2300 lines of code, v2 has ~350 lines of code.</b>
3
+ <b>Searchlogic has been <em>completely</em> rewritten for v2. It is much simpler and has taken an entirely new approach. To give you an idea, v1 had ~2300 lines of code, v2 has ~420 lines of code.</b>
4
4
 
5
- <b>Attention v1 users. v2 breaks backwards compatibility. Please make sure your gem declaration for searchlogic looks like this so that you app does not break when the gem is updated: config.gem "searchlogic", :version => "~> 1.6.6"</b>
5
+ <b>Attention v1 users. To start using v2 you must use the binarylogic-searchlogic gem. I have decided to start using github to host my gems. See below for installation instructions.</b>
6
6
 
7
- Searchlogic provides common named scopes and object based searching.
7
+ Searchlogic provides common named scopes and object based searching for ActiveRecord.
8
8
 
9
9
  == Helpful links
10
10
 
@@ -25,7 +25,7 @@ In your rails project:
25
25
  config.gem "binarylogic-searchlogic",
26
26
  :lib => 'searchlogic',
27
27
  :source => 'http://gems.github.com',
28
- :version => '0.6.6'
28
+ :version => '~> 2.0.0'
29
29
 
30
30
  Then install the gem:
31
31
 
@@ -68,7 +68,7 @@ Any named scope Searchlogic creates is dynamic and created via method_missing. M
68
68
 
69
69
  That's all pretty standard, but here's where Searchlogic starts to get interesting...
70
70
 
71
- == Search using conditions on association columns
71
+ == Search using conditions on associated columns
72
72
 
73
73
  You also get named scopes for any of your associations:
74
74
 
@@ -101,15 +101,27 @@ If you want to use the :include option, just specify it:
101
101
 
102
102
  Obviously, only do this if you want to actually use the included objects.
103
103
 
104
+ Lastly, because we are using ActiveRecord, named scopes, combining conditions, and ordering based on associated columns, the decision was made to use left outer joins instead of inner joins. This allows us to be consistent, include optional associations when ordering, and avoid duplicate joins when eager loading associations. If we use an inner join and combine any of these things we will get an "ambiguous name" sql error for the table being joined twice. Just like anything, be mindful of the SQL being produced in your application. If you are joining beyond 4 or 5 levels deep then you might consider looking at the query and optimizing it. Part of that optimization may require the use of inner joins depending on the query.
105
+
104
106
  == Make searching and ordering data in your application trivial
105
107
 
106
- The above is great, but what about tying all of this in with a search form in your application? Just do this...
108
+ The above is great, but what about tying all of this in with a search form in your application? What would be really nice is if we could use an object that represented a single search. Like this...
107
109
 
108
- User.search(:username_like => "bjohnson", :age_less_than => 20)
110
+ search = User.search(:username_like => "bjohnson", :age_less_than => 20)
111
+ search.all
109
112
 
110
113
  The above is equivalent to:
111
114
 
112
- User.username_like("bjohnson").age_less_than(20)
115
+ User.username_like("bjohnson").age_less_than(20).all
116
+
117
+ You can set, read, and chain conditions off of your search too:
118
+
119
+ search.username_like => "bjohnson"
120
+ search.age_gt = 2 => 2
121
+ search.id_gt(10).email_begins_with("bjohnson") => <#Searchlogic::Search...>
122
+ search.all => An array of users
123
+ search.count => integer
124
+ # .. etc
113
125
 
114
126
  All that the search method does is chain named scopes together for you. What's so great about that? It keeps your controllers extremely simple:
115
127
 
@@ -159,9 +171,9 @@ What's great about this is that you can do just about anything you want. If Sear
159
171
 
160
172
  Every condition you've seen in this readme also has 2 related conditions that you can use. Example:
161
173
 
162
- User.username_like_any("bjohnson", "thunt") # will return any users that have either of those strings in their username
163
- User.username_like_all("bjohnson", "thunt") # will return any users that have all of those string in their username
164
- User.username_like_any(["bjohnson", "thunt"]) # also accept an array
174
+ User.username_like_any("bjohnson", "thunt") # will return any users that have either of the strings in their username
175
+ User.username_like_all("bjohnson", "thunt") # will return any users that have all of the strings in their username
176
+ User.username_like_any(["bjohnson", "thunt"]) # also accepts an array
165
177
 
166
178
  This is great for checkbox filters, etc. Where you can pass an array right from your form to this condition.
167
179
 
@@ -180,7 +192,7 @@ Before I use a library in my application I like to glance at the source and try
180
192
 
181
193
  Searchlogic utilizes method_missing to create all of these named scopes. When it hits method_missing it creates a named scope to ensure it will never hit method missing for that named scope again. Sort of a caching mechanism. It works in the same fashion as ActiveRecord's "find_by_*" methods. This way only the named scopes you need are created and nothing more.
182
194
 
183
- That's about it, the named scope options are pretty bare bones and created just like you would manually.
195
+ That's about it, the named scope options are pretty bare bones and created just like you would manually. The only big difference being the use of LEFT OUTER JOINS on associated conditions instead of INNER JOINS.
184
196
 
185
197
  == Credit
186
198
 
data/Rakefile CHANGED
@@ -5,9 +5,9 @@ begin
5
5
  require 'jeweler'
6
6
  Jeweler::Tasks.new do |gem|
7
7
  gem.name = "searchlogic"
8
- gem.summary = "Searchlogic provides common named scopes and object based searching."
8
+ gem.summary = "Searchlogic provides common named scopes and object based searching for ActiveRecord."
9
9
  gem.email = "bjohnson@binarylogic.com"
10
- gem.homepage = "http://github.com/binarylogic/search"
10
+ gem.homepage = "http://github.com/binarylogic/searchlogic"
11
11
  gem.authors = ["Ben Johnson of Binary Logic"]
12
12
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
13
13
  end
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
- ---
1
+ ---
2
2
  :major: 2
3
3
  :minor: 0
4
- :patch: 0
4
+ :patch: 1
@@ -29,6 +29,24 @@ module Searchlogic
29
29
  !association_alias_condition_details(name).nil?
30
30
  end
31
31
 
32
+ # Leverages ActiveRecord's JoinDependency class to create a left outer join. Searchlogic uses left outer joins so that
33
+ # records with no associations are included in the result when the association is optional. You can use this method
34
+ # internally when creating your own named scopes that need joins. You need to do this because then ActiveRecord will
35
+ # remove any duplicate joins for you when you chain named scopes that require the same join. If you are using a
36
+ # LEFT OUTER JOIN and an INNER JOIN, ActiveRecord will add both to the query, causing SQL errors.
37
+ #
38
+ # Bottom line, this is convenience method that you can use when creating your own named scopes. Ex:
39
+ #
40
+ # named_scope :orders_line_items_price_expensive, :joins => left_out_joins(:orders => :line_items), :conditions => "line_items.price > 100"
41
+ #
42
+ # Now your joins are consistent with Searchlogic allowing you to avoid SQL errors with duplicate joins.
43
+ def left_outer_joins(association_name)
44
+ ActiveRecord::Associations::ClassMethods::JoinDependency.new(self, association_name, nil).join_associations.collect do |assoc|
45
+ sql = assoc.association_join.strip
46
+ sql.split(/LEFT OUTER JOIN/).delete_if { |join| join.strip.blank? }.collect { |join| "LEFT OUTER JOIN #{join.strip}"}
47
+ end.flatten
48
+ end
49
+
32
50
  private
33
51
  def method_missing(name, *args, &block)
34
52
  if details = association_condition_details(name)
@@ -135,9 +153,9 @@ module Searchlogic
135
153
  #
136
154
  # The code below was extracted out of AR's add_joins! method and then modified.
137
155
  def add_left_outer_joins(options, association)
138
- join = ActiveRecord::Associations::ClassMethods::JoinDependency.new(self, association.name, nil).join_associations.collect { |assoc| assoc.association_join }.join.strip
156
+ joins = left_outer_joins(association.name)
139
157
  options[:joins] ||= []
140
- options[:joins].unshift(join)
158
+ options[:joins] = joins + options[:joins]
141
159
  end
142
160
  end
143
161
  end
@@ -46,7 +46,7 @@ module Searchlogic
46
46
  # ActiveRecord hides this internally, so we have to try and pull it out with this
47
47
  # method.
48
48
  def named_scope_options(name)
49
- key = primary_condition_name(name)
49
+ key = scopes.key?(name.to_sym) ? name.to_sym : primary_condition_name(name)
50
50
 
51
51
  if key
52
52
  eval("options", scopes[key])
@@ -46,6 +46,10 @@ module Searchlogic
46
46
  self.conditions = conditions if conditions.is_a?(Hash)
47
47
  end
48
48
 
49
+ def clone
50
+ self.class.new(klass, current_scope.clone, conditions.clone)
51
+ end
52
+
49
53
  # Returns a hash of the current conditions set.
50
54
  def conditions
51
55
  @conditions ||= {}
@@ -71,7 +75,12 @@ module Searchlogic
71
75
  raise UnknownConditionError.new(name)
72
76
  end
73
77
  elsif scope?(normalize_scope_name(name))
74
- conditions[name]
78
+ if args.size > 0
79
+ send("#{name}=", *args)
80
+ self
81
+ else
82
+ conditions[name]
83
+ end
75
84
  else
76
85
  scope = conditions.inject(klass.scoped(current_scope)) do |scope, condition|
77
86
  scope_name, value = condition
@@ -0,0 +1,65 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{searchlogic}
5
+ s.version = "2.0.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Ben Johnson of Binary Logic"]
9
+ s.date = %q{2009-06-20}
10
+ s.email = %q{bjohnson@binarylogic.com}
11
+ s.extra_rdoc_files = [
12
+ "LICENSE",
13
+ "README.rdoc"
14
+ ]
15
+ s.files = [
16
+ ".gitignore",
17
+ "CHANGELOG.rdoc",
18
+ "LICENSE",
19
+ "README.rdoc",
20
+ "Rakefile",
21
+ "VERSION.yml",
22
+ "init.rb",
23
+ "lib/searchlogic.rb",
24
+ "lib/searchlogic/core_ext/object.rb",
25
+ "lib/searchlogic/core_ext/proc.rb",
26
+ "lib/searchlogic/named_scopes/associations.rb",
27
+ "lib/searchlogic/named_scopes/conditions.rb",
28
+ "lib/searchlogic/named_scopes/ordering.rb",
29
+ "lib/searchlogic/rails_helpers.rb",
30
+ "lib/searchlogic/search.rb",
31
+ "rails/init.rb",
32
+ "searchlogic.gemspec",
33
+ "spec/core_ext/object_spec.rb",
34
+ "spec/core_ext/proc_spec.rb",
35
+ "spec/named_scopes/associations_spec.rb",
36
+ "spec/named_scopes/conditions_spec.rb",
37
+ "spec/named_scopes/ordering_spec.rb",
38
+ "spec/search_spec.rb",
39
+ "spec/spec_helper.rb"
40
+ ]
41
+ s.homepage = %q{http://github.com/binarylogic/searchlogic}
42
+ s.rdoc_options = ["--charset=UTF-8"]
43
+ s.require_paths = ["lib"]
44
+ s.rubygems_version = %q{1.3.4}
45
+ s.summary = %q{Searchlogic provides common named scopes and object based searching for ActiveRecord.}
46
+ s.test_files = [
47
+ "spec/core_ext/object_spec.rb",
48
+ "spec/core_ext/proc_spec.rb",
49
+ "spec/named_scopes/associations_spec.rb",
50
+ "spec/named_scopes/conditions_spec.rb",
51
+ "spec/named_scopes/ordering_spec.rb",
52
+ "spec/search_spec.rb",
53
+ "spec/spec_helper.rb"
54
+ ]
55
+
56
+ if s.respond_to? :specification_version then
57
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
58
+ s.specification_version = 3
59
+
60
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
61
+ else
62
+ end
63
+ else
64
+ end
65
+ end
@@ -119,6 +119,6 @@ describe "Associations" do
119
119
  company = Company.create
120
120
  user = company.users.create(:username => "bjohnson")
121
121
  order = user.orders.create(:total => 20, :taxes => 3)
122
- Company.ascend_by_users_orders_total.users_orders_taxes_lt(50).all(:include => {:users => :orders}).should == Company.all
122
+ Company.users_orders_taxes_lt(50).ascend_by_users_orders_total.all(:include => {:users => :orders}).should == Company.all
123
123
  end
124
124
  end
data/spec/search_spec.rb CHANGED
@@ -29,6 +29,17 @@ describe "Search" do
29
29
  end
30
30
  end
31
31
 
32
+ it "should clone properly" do
33
+ company = Company.create
34
+ user1 = company.users.create(:age => 5)
35
+ user2 = company.users.create(:age => 25)
36
+ search1 = company.users.search(:age_gt => 10)
37
+ search2 = search1.clone
38
+ search2.age_gt = 1
39
+ search2.all.should == User.all
40
+ search1.all.should == [user2]
41
+ end
42
+
32
43
  context "conditions" do
33
44
  it "should set the conditions and be accessible individually" do
34
45
  search = User.search
@@ -68,6 +79,14 @@ describe "Search" do
68
79
  search.username_gt.should == "bjohnson"
69
80
  end
70
81
 
82
+ it "should allow chainging conditions" do
83
+ user = User.create(:username => "bjohnson", :age => 20)
84
+ User.create(:username => "bjohnson", :age => 5)
85
+ search = User.search
86
+ search.username_equals("bjohnson").age_gt(10)
87
+ search.all.should == [user]
88
+ end
89
+
71
90
  it "should allow setting association conditions" do
72
91
  search = User.search
73
92
  search.orders_total_gt = 10
@@ -92,13 +111,20 @@ describe "Search" do
92
111
  search.username_gt.should == "bjohnson2"
93
112
  end
94
113
 
95
- it "should allow setting custom conditions individually" do
114
+ it "should allow setting custom conditions individually with an arity of 0" do
96
115
  User.named_scope(:four_year_olds, :conditions => {:age => 4})
97
116
  search = User.search
98
117
  search.four_year_olds = true
99
118
  search.four_year_olds.should == true
100
119
  end
101
120
 
121
+ it "should allow setting custom conditions individually with an arity of 1" do
122
+ User.named_scope(:username_should_be, lambda { |u| {:conditions => {:username => u}} })
123
+ search = User.search
124
+ search.username_should_be = "bjohnson"
125
+ search.username_should_be.should == "bjohnson"
126
+ end
127
+
102
128
  it "should not allow setting conditions that are not scopes" do
103
129
  search = User.search
104
130
  lambda { search.unknown = true }.should raise_error(Searchlogic::Search::UnknownConditionError)
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: binarylogic-searchlogic
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
- - binarylogic
7
+ - Ben Johnson of Binary Logic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-06-15 00:00:00 -07:00
12
+ date: 2009-06-20 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -24,6 +24,7 @@ extra_rdoc_files:
24
24
  - README.rdoc
25
25
  files:
26
26
  - .gitignore
27
+ - CHANGELOG.rdoc
27
28
  - LICENSE
28
29
  - README.rdoc
29
30
  - Rakefile
@@ -38,6 +39,7 @@ files:
38
39
  - lib/searchlogic/rails_helpers.rb
39
40
  - lib/searchlogic/search.rb
40
41
  - rails/init.rb
42
+ - searchlogic.gemspec
41
43
  - spec/core_ext/object_spec.rb
42
44
  - spec/core_ext/proc_spec.rb
43
45
  - spec/named_scopes/associations_spec.rb
@@ -66,11 +68,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
66
68
  version:
67
69
  requirements: []
68
70
 
69
- rubyforge_project: test
71
+ rubyforge_project:
70
72
  rubygems_version: 1.2.0
71
73
  signing_key:
72
74
  specification_version: 3
73
- summary: TODO
75
+ summary: Searchlogic provides common named scopes and object based searching for ActiveRecord.
74
76
  test_files:
75
77
  - spec/core_ext/object_spec.rb
76
78
  - spec/core_ext/proc_spec.rb