I have this code on model class to add search methods to be used by meta_search
gem:
class Model
self.def created_at_lteq_at_end_of_day(date)
where("created_at <= ?", DateTime.strptime(date, '%d/%m/%Y').end_of_day)
end
search_methods :created_at_lteq_at_end_of_day
end
This code add search methods to date field. Now, is needed to add this search method to other classes and with others fields. To achieve this, this module was created:
lib/meta_search/extended_search_methods.rb
module MetaSearch
module ExtendedSearchMethods
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def add_search_by_end_of_day(field, format)
method_name = "#{field}_lteq_end_of_day"
define_method method_name do |date|
where("#{field} <= ?", DateTime.strptime(date, format).end_of_day)
end
search_methods method_name
end
end
end
end
class Model
include MetaSearch::ExtendedSearchMethods
add_search_by_end_of_day :created_at, '%d/%m/%Y'
end
After add the module, this errors starts to rise:
undefined method `created_at_lteq_end_of_day' for #<ActiveRecord::Relation:0x007fcd3cdb0e28>
Other solution:
change define_method
to define_singleton_method
ActiveSupport provides a pretty idiomatic and cool way of doing that, ActiveSupport::Concern
:
module Whatever
extend ActiveSupport::Concern
module ClassMethods
def say_hello_to(to)
puts "Hello #{to}"
end
end
end
class YourModel
include Whatever
say_hello_to "someone"
end
See the API doc. Although it is not directly related to your question, the included
method is incredibly useful for models or controllers (scopes, helper methods, filters, etc), plus ActiveSupport::Concern
handles dependencies between modules for free (both as in freedom and as in beer).