繁体   English   中英

如何使用模块动态地将类方法添加到Rails模型

[英]How to dynamically add class methods to Rails Models using module

我在模型类上有这个代码来添加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

此代码将搜索方法添加到日期字段。 现在,需要将此搜索方法添加到其他类和其他字段。 为此,创建了此模块:

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_method更改为define_singleton_method

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文档 虽然它与您的问题没有直接关系,但是included方法对于模型或控制器(范围,辅助方法,过滤器等)非常有用, ActiveSupport::Concern可以免费处理模块之间的依赖关系(无论是在自由中还是在啤酒)。

你需要添加一个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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM