动态地包括Rails Concern

时间:2015-05-14 01:44:28

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

我的目标是根据设置的属性动态加载一组方法到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']

我假设这是因为'include'发生在类级别而不是实例级别。希望能有一些帮助,如何清理它并使这项工作。

1 个答案:

答案 0 :(得分:1)

使用answer 将实例方法添加到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