Skip to content

Commit

Permalink
Added example in readme for adding your own conditions
Browse files Browse the repository at this point in the history
  • Loading branch information
binarylogic committed Sep 3, 2008
1 parent aa89fc3 commit e8274f3
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 113 deletions.
38 changes: 38 additions & 0 deletions README.mdown
Expand Up @@ -250,6 +250,44 @@ Some of these conditions come with aliases, so you have your choice how to call

You will notice above there is "contains" and "keywords". The difference is that "keywords" is an enhanced search. It acts like a real keyword search. It finds those keywords, in any order, and blacklists meaningless words such as "and", "the", etc. "contains" finds the EXACT string in the column you are searching, spaces and all.

### Roll your own conditions

I didn't include this function because its MySQL specific, and it's probably rarely used, but MySQL supports a "SOUNDS LIKE" function.

I want to use it, so let's add it:

# config/initializers/searchgasm.rb
# Actual function for MySQL databases only
class SoundsLikeCondition < Searchgasm::Condition
class << self
# I pass you the column, you tell me what you want the method to be called.
# If you don't want to add this condition for that column, return nil
# It defaults to "#{column.name}_sounds_like". So if thats what you want you don't even need to do this.
def name_for_column(column)
super
end
# Only do this if you want aliases for your condition
def aliases_for_column(column)
["#{column.name}_sounds", "#{column.name}_similar_to"]
end
end
def to_conditions(value)
["#{quoted_table_name}.#{quoted_column_name} SOUNDS LIKE ?", value]
end
end

Searchgasm::Condition.register_condition(SoundsLikeCondition)

Now test it out:

search = User.new_search
search.first_name_sounds_like = "Ben"
search.all # will return any user that has a first name that sounds like "Ben"

Pretty nifty, huh? You can create any condition ultimately creating any SQL you want. The sky is the limit.

## Credits

Author: [Ben Johnson](http://github.com/binarylogic) of [Binary Logic](http://www.binarylogic.com)
Expand Down
2 changes: 1 addition & 1 deletion lib/searchgasm.rb
Expand Up @@ -5,11 +5,11 @@

require "searchgasm/version"
require "searchgasm/search/utilities"
require "searchgasm/search/condition"
require "searchgasm/search/conditions"
require "searchgasm/search/base"

# Regular conidtion types
require "searchgasm/search/condition_types/condition"
require "searchgasm/search/condition_types/begins_with_condition"
require "searchgasm/search/condition_types/contains_condition"
require "searchgasm/search/condition_types/does_not_equal_condition"
Expand Down
105 changes: 105 additions & 0 deletions lib/searchgasm/search/condition.rb
@@ -0,0 +1,105 @@
module BinaryLogic
module Searchgasm
module Search
class Condition
include Utilities

attr_accessor :column, :klass
attr_reader :value

class << self
def condition_name
name.split("::").last.scan(/(.*)Condition/)[0][0].underscore
end

def name_for_column(column)
"#{column.name}_#{condition_name}"
end

def aliases_for_column(column)
[]
end

def name_for_klass(klass)
nil
end

def aliases_for_klass(klass)
[]
end

def string_column?(column)
[:string, :text].include?(column.type)
end

def comparable_column?(column)
[:integer, :float, :decimal, :datetime, :timestamp, :time, :date].include?(column.type)
end
end

def initialize(klass, column = nil)
self.klass = klass
self.column = column.is_a?(String) ? klass.columns_hash[column] : column
end

def explicitly_set_value=(value)
@explicitly_set_value = value
end

# Need this if someone wants to actually use nil in a meaningful way
def explicitly_set_value?
@explicitly_set_value == true
end

def ignore_blanks?
true
end

def name
column ? self.class.name_for_column(column) : self.class.name_for_klass(klass)
end

def condition_name
self.class.condition_name
end

def quote_column_name(column_name)
klass.connection.quote_column_name(column_name)
end

def quoted_column_name
quote_column_name(column.name)
end

def quote_table_name(table_name)
klass.connection.quote_table_name(table_name)
end

def quoted_table_name
quote_table_name(klass.table_name)
end

def sanitize(alt_value = nil)
return unless explicitly_set_value?
v = alt_value || value
if v.is_a?(Array) && !["equals", "does_not_equal"].include?(condition_name)
merge_conditions(*v.collect { |i| sanitize(i) })
else
v = v.utc if column && [:time, :timestamp, :datetime].include?(column.type) && klass.time_zone_aware_attributes && !klass.skip_time_zone_conversion_for_attributes.include?(column.name.to_sym)
to_conditions(v)
end
end

def value
@value.is_a?(String) ? column.type_cast(@value) : @value
end

def value=(v)
return if ignore_blanks? && v.blank?
self.explicitly_set_value = true
@value = v
end
end
end
end
end
Expand Up @@ -23,6 +23,4 @@ def to_conditions(value)
Conditions.register_condition(ConditionTypes::BeginsWithCondition)
end
end
end

BinaryLogic::Searchgasm::Search::Conditions.register_condition(BinaryLogic::Searchgasm::Search::ConditionTypes::BeginsWithCondition)
end
107 changes: 0 additions & 107 deletions lib/searchgasm/search/condition_types/condition.rb

This file was deleted.

4 changes: 2 additions & 2 deletions lib/searchgasm/search/conditions.rb
Expand Up @@ -8,8 +8,8 @@ class Conditions

class << self
def register_condition(klass)
raise(ArgumentError, "You can only register conditions that extend BinaryLogic::Searchgasm::Search::ConditionTypes::Condition") unless klass.ancestors.include?(ConditionTypes::Condition)
conditions << klass
raise(ArgumentError, "You can only register conditions that extend BinaryLogic::Searchgasm::Search::ConditionTypes::Condition") unless klass.ancestors.include?(Condition)
conditions << klass unless conditions.include?(klass)
end

def conditions
Expand Down

0 comments on commit e8274f3

Please sign in to comment.