【问题标题】:Dynamically including a Rails Concern动态包含 Rails 问题
【发布时间】:2015-05-14 01:44:28
【问题描述】:

我的目标是根据设置的属性将一组方法动态加载到 ActiveRecord 模型实例:

class Book < ActiveRecord::Base
  after_initialize do |cp|
    self.class.include "#{cp.subject}".constantize
  end
end

然后我有以下顾虑:

module Ruby
    extend ActiveSupport::Concern
    def get_framework
        'rails'
    end
end

module Python
    extend ActiveSupport::Concern
    def get_framework
        'django'
    end
end

然后,当我单独运行这些时,我得到了正确的框架字符串:

python_book = Book.create(:subject => 'python', :id => 1)
python_book.get_framework -> 'django'

ruby_book = Book.create(:subject => 'ruby', :id => 2)
ruby_book.get_framework -> 'rails'

我的问题是,当我在查询中返回两本书时,包含的关注是结果集中的最后一个,并且没有选择正确的关注方法。

Books.all.order(:id => 'asc').collect do |book|
    puts book.get_framework
end

# Result
['rails', 'rails']

我假设这是因为“包含”发生在类级别而不是实例级别。希望得到一些关于如何清理它并使其工作的帮助。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4


    【解决方案1】:

    使用.extend 而是将实例方法添加到 Book 的实例中。

    在行动中扩展:

    module Greeter
      def say_hello
        "Hello"
      end
    end
    

    irb(main):008:0> a = Object.new
    => #<Object:0x00000101e01c38>
    irb(main):009:0> a.extend(Greeter)
    => #<Object:0x00000101e01c38>
    irb(main):010:0> a.say_hello
    => "Hello"
    irb(main):011:0> Object.new.say_hello
    NoMethodError: undefined method `say_hello' for #<Object:0x00000101e196d0>
    

    class Book < ActiveRecord::Base
      after_initialize do |cp|
        self.extend subject.constantize
      end
    end
    

    【讨论】:

    • 是的,我只是打了自己的额头。这很有效,感谢您的解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多