0

我对模型类的代码添加搜索方法由meta_search宝石可以使用动态添加类的方法到Rails模型:如何使用模块

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 

该代码添加搜索方法日期字段。 现在,需要将此搜索方法添加到其他类和其他字段。 为了实现这一目标,该模块被创造:

的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 

添加模块后,这个错误开始上升:

undefined method `created_at_lteq_end_of_day' for #<ActiveRecord::Relation:0x007fcd3cdb0e28> 

其他解决方案:

更改define_methoddefine_singleton_method

+0

您是否包含MetaSearch? – screenmutt

回答

8

的ActiveSupport提供这样做,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 

API doc。虽然它与你的问题没有直接关系,但是included方法对模型或控制器(范围,辅助方法,过滤器等)非常有用,另外还可以免费处理模块之间的依赖关系(无论是在自由还是在啤酒中)。

5

您需要添加class << self,以便您在单工类中工作。

module Library 
    module Methods 
    def self.included(base) 
     base.extend ClassMethods 
    end 

    module ClassMethods 
     def add_foo 
     class << self 
      define_method "foo" do 
      puts "Foo!" 
      end #define_method 
     end #class << self 
     end #add_foo 
    end #ClassMethods 
    end #Methods 
end #Library 

class Test 
    include Library::Methods 

    add_foo 
end 

puts Test.foo 
+0

谢谢!为我工作很好。 – Mavvie