2012-03-09 97 views
5

我想將我的幾個模型類擴展到「資產」類。 這四種類型的Assets中的每一種都能夠生成一個slug從而避免set_callback(:save, :before)因此,我不想寫出四種相同的方法,而是希望他們擴展一個Asset類,該類將具有set_callback(以及其他方法)。Mongoid的Rails模塊

起初我試着簡單地讓它們擴展Asset類,但遇到了問題,當我將其中一個資產保存到數據庫(mongo)時,它們插入的集合稱爲Asset而不是它們自己的名稱。

在我搜索周圍的人似乎推薦使用模塊來代替。所以,我已經試過了:

module Asset 
    field :slug, :type => String 

    set_callback(:save, :before) do |document| 
    # make document.slug = to whatever 
    end 
end 

class Video 
    include Mongoid::Document 
    include Asset 
    field :video_name, :type => String 
    field :description, :type => String 
    field :some_more_fields, :type => String 
end 

,但我得到了一些錯誤,當我包括資產:

'undefined method `field' for Asset:Module' 

注:我使用Mongoid

回答

7

方法字段沒有在已知資產模塊的上下文。所以,你必須調用只有當模塊包括現場:

module Asset 
    def self.included(base) 
     base.send(:field, :slug, :type => String) 
    end 
    end 

編輯:在代碼塊包裝代碼

+0

謝謝,對我很好。在我的Notifiable模塊中也使用'''base.send(:before_create,:notify_on_create)''和''base.send(:embeds_many,:notifications,:as =>:notifiable)'''' – genkilabs 2013-07-26 20:02:37

+0

你將如何去發送聲明在該模塊範圍? – Alex 2013-12-09 00:01:12

+0

我得到'包含':資產:模塊(NoMethodError)未定義的方法'字段'。也許這不適用於Ruby 2.3.1? – 2016-05-06 18:10:08

2

好,使用的擔憂使得這麼多更容易和更好的寫:

module Asset 
include extend ActiveSupport::Concern 
    included do 
    field: slug, type: String 
    before_create: :notify_on_create 
    scope: my_scope, ->(var) { where(slug: var) } 
    end 
end 
end 

查看http://api.rubyonrails.org/classes/ActiveSupport/Concern.html瞭解更多詳情。