2015-05-14 52 views
0

我的目標是動態地加載一組的方法來基於屬性ActiveRecord模型實例我們設置:動態包括一個Rails關注

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' 

我的問題lem是,當我在查詢中返回兩本書時,包含的關注點是結果集中的最後一個,並且沒有選擇正確的關注方法。

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

# Result 
['rails', 'rails'] 

我假設這是因爲'包含'發生在類級而不是實例級。會喜歡一些幫助,以便如何清理並完成這項工作。

回答

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 
+0

啊,我只是砸到自己在額頭上。這工作,並感謝解釋。 – daxiang28