Permalink
Browse files

Release v1.5.6 (see changelog)

  • Loading branch information...
1 parent 678c444 commit 585e1459eaf69c71d0896a4c7b47529ad47b9960 @binarylogic binarylogic committed Nov 29, 2008
View
@@ -1,3 +1,10 @@
+== 1.5.6 released 2008-11-17
+
+* 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.
+* The above allows for prefixing any condition with and_ or or_. Thus letting you create somewhat more complex queries, since the order matters.
+* Added ability to group conditions to mimic parenthesis in raw SQL.
+* Major clean up in the Searchlogic::Conditions name space: faster, smaller, cleaner, and modular.
+
== 1.5.5 released 2008-11-17
* Cleaned up class_name configuration for helpers, so that setting them to nil disables the class name
View
@@ -1,6 +1,6 @@
= Searchlogic
-Searchlogic is object based ActiveRecord searching, ordering, and pagination all in one.
+Searchlogic is object based ActiveRecord searching, ordering, and pagination all in one. It's a simple, quick, all inclusive package for displaying data in your application.
== Helpful links
@@ -178,17 +178,84 @@ Any of the options used in the above example can be used in these, but for the s
search.per_page = 20
search.all
+ search = User.new_search(:conditions => {:age_gt => 18}) do |s|
+ s.conditions.first_name_contains = "Ben"
+ s.per_page = 20
+ end
+ search.all
+
== Match ANY or ALL of the conditions
As you saw above, the nice thing about Searchlogic is it's integration with forms. I designed the "any" option so that forms can set this as well, just like a condition.
- @search = User.new_search(:conditions => {:age_gt => 18}) do |search|
- search.conditions.first_name_contains = "Ben"
- search.conditions.any = true # can set this to "true" or "1" or "yes"
- search.all # will join all conditions with "or" instead of "and"
- end
+ @search = User.new_search(:conditions => {:age_gt => 18})
+ @search.conditions.first_name_contains = "Ben"
+ @search.conditions.any = true # can set this to "true" or "1" or "yes"
+ @search.all # will join all conditions with "or" instead of "and"
# ... all operations above are available
+What if you want to mix and match?
+
+ @search = User.new_search(:conditions => {:age_gt => 18})
+ @search.conditions.or_first_name_contains = "Ben"
+ @search.conditions.or_last_name_contains = "Johnson"
+ @search.conditions.and_id_gt = 5 # the and_ is optional, calling just id_gt is the same thing
+ @search.all # will join conditions in the orders they were set with their specified join condition
+ # => age > 17 OR first_name like '%Ben%' OR lsat_name like '%Johnson%' AND id > 5
+
+The order the conditions is set is relevant, as the SQL will be built in the same order.
+
+== Grouping conditions
+
+In more complex searching situations you might want to group conditions. Just like you use parenthesis in raw SQL. Searchlogic's "group" function is basically a way to implement parenthesis in your conditions. It's simple:
+
+Group off an object:
+
+ search = User.new_search
+ search.id_gt = 2
+ group1 = search.conditions.group
+ group.first_name_like = "Ben"
+ group2 = search.conditions.group
+ group.last_name_like = "Johnson"
+ group21 = group2.group
+ group21.email_ends_with = "binarylogic.com"
+ # => id > 2 AND (first_name like '%Ben%') AND (last_name like '%Johnson%' AND (email like '%binarylogic.com'))
+
+Group with a block:
+
+ search = User.new_search
+ search.id_gt = 2
+ search.conditions.group do |group|
+ group.first_name_like = "Ben"
+ end
+ search.conditions.group do |group|
+ group.last_name_like = "Johnson"
+ group.group do |sub_group|
+ sub_group.email_ends_with = "binarylogic.com"
+ end
+ end
+ # => id > 2 AND (first_name like '%Ben%') AND (last_name like '%Johnson%' AND (email like '%binarylogic.com'))
+
+Group with a hash:
+
+ search = User.new_search(:conditions => {
+ :id_gt => 2,
+ :group => [
+ {:first_name_like => "Ben"},
+ {
+ :last_name_like => "Johnson",
+ :group => {:email_ends_with => "binarylogic.com"}
+ }
+ ]
+ })
+ # => id > 2 AND (first_name like '%Ben%') AND (last_name like '%Johnson%' AND (email like '%binarylogic.com'))
+
+I want to end this by saying Searchlog was never meant to replace SQL, name_scopes, etc. If you need to perform complex searching there is nothing wrong with resorting to a named scope or using the traditional search methods. In fact, search logic plays nice with named_scopes anyways, so you can combine the 2 if needed:
+
+ @search = User.my_awesome_scope.another_cool_scope.new_search
+
+The only reason I added this was to allow searchlogic to extend a little further into those advanced searches. If you need to scope conditions by using parenthesis, etc. you should resort to named_scopes or the traditional search method.
+
== Scoped searching
@current_user.orders.find(:all, :conditions => {:total_lte => 500})
View
@@ -1,14 +1,19 @@
require 'rubygems'
-require 'echoe'
-
require File.dirname(__FILE__) << "/lib/searchlogic/version"
-Echoe.new 'searchlogic' do |p|
- p.version = Searchlogic::Version::STRING
- p.author = "Ben Johnson of Binary Logic"
- p.email = 'bjohnson@binarylogic.com'
- p.project = 'searchlogic'
- p.summary = "Object based ActiveRecord searching, ordering, pagination, and more!"
- p.url = "http://github.com/binarylogic/searchlogic"
- p.dependencies = %w(activerecord activesupport)
+begin
+ require 'echoe'
+
+ Echoe.new 'searchlogic' do |p|
+ p.version = Searchlogic::Version::STRING
+ p.author = "Ben Johnson of Binary Logic"
+ p.email = 'bjohnson@binarylogic.com'
+ p.project = 'searchlogic'
+ p.summary = "Object based ActiveRecord searching, ordering, pagination, and more!"
+ p.url = "http://github.com/binarylogic/searchlogic"
+ p.dependencies = %w(activerecord activesupport)
+ end
+rescue LoadError => boom
+ puts "You are missing a dependency required for meta-operations on this gem."
+ puts "#{boom.to_s.capitalize}."
end
View
@@ -38,6 +38,9 @@
require "searchlogic/search/protection"
# Conditions
+require "searchlogic/conditions/any_or_all"
+require "searchlogic/conditions/groups"
+require "searchlogic/conditions/magic_methods"
require "searchlogic/conditions/protection"
require "searchlogic/conditions/base"
@@ -76,6 +79,9 @@ class Base
module Conditions
class Base
+ include AnyOrAll
+ include Groups
+ include MagicMethods
include Protection
end
@@ -7,7 +7,7 @@ module Condition # :nodoc:
class Base
include Shared::Utilities
- attr_accessor :column, :column_for_type_cast, :column_sql, :column_sql_format, :klass, :table_name
+ attr_accessor :any, :column, :column_for_type_cast, :column_sql, :column_sql_format, :klass, :object_name, :table_name
class_inheritable_accessor :handle_array_value, :ignore_meaningless_value, :join_arrays_with_or, :value_type
self.ignore_meaningless_value = true
@@ -61,6 +61,10 @@ def initialize(klass, options = {})
end
end
+ def any? # :nodoc:
+ any == true
+ end
+
# Substitutes string vars with table and column name. Allows us to switch the column and table on the fly and have the condition update appropriately.
# The table name could be variable depending on the condition. Take STI and more than one child model is used in the condition, the first gets the parent table name, the rest get aliases.
def column_sql
@@ -0,0 +1,42 @@
+module Searchlogic
+ module Conditions
+ # = Any or All
+ #
+ # Adds the ability to join all conditions wth "ANY" or "ALL".
+ module AnyOrAll
+ # Determines if we should join the conditions with "AND" or "OR".
+ #
+ # === Examples
+ #
+ # search.conditions.any = true # will join all conditions with "or", you can also set this to "true", "1", or "yes"
+ # search.conditions.any = false # will join all conditions with "and"
+ def any=(value)
+ objects.each { |object| object.any = value }
+ @any = value
+ end
+
+ def any # :nodoc:
+ any?
+ end
+
+ # Convenience method for determining if we should join the conditions with "AND" or "OR".
+ def any?
+ ["true", "1", "yes"].include? @any.to_s
+ end
+
+ # Sets the conditions to be searched by "or"
+ def any!
+ self.any = true
+ end
+
+ def all? # :nodoc:
+ !any?
+ end
+
+ # Sets the conditions to be searched by "and"
+ def all!
+ self.any = false
+ end
+ end
+ end
+end
Oops, something went wrong.

0 comments on commit 585e145

Please sign in to comment.