2012-03-09 10 views
5

Sto provando ad estendere alcune delle mie classi modello a una classe "Asset". Ciascuno dei quattro tipi di risorse sarà in grado di generare una lumaca su un set_callback(:save, :before) Di conseguenza, invece di scrivere quattro metodi uguali, vorrei che estendessero una classe di asset che avrebbe il set_callback (così come altri metodi).Modulo Rails con Mongolo

In un primo momento ho provato semplicemente ad averli estendere la classe di asset, ma mi sono imbattuto in problemi in cui quando ho salvato uno degli asset nel database (mongo), la raccolta inserita è stata chiamata Asset piuttosto che il proprio nome.

Dopo aver cercato su Google le persone sembrano raccomandare l'uso dei moduli. Così ho provato:

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 

Ma ho alcuni errori quando includo Asset:

'undefined method `field' for Asset:Module' 

Nota: sto usando Mongoid

risposta

7

Il campo metodo non è noto nel contesto del modulo Asset. Quindi devi chiamare campo solo quando il modulo è incluso:

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

Edit: Codice avvolto in blocco di codice

+0

Grazie, ha funzionato benissimo per me. Usato anche '' 'base.send (: before_create,: notify_on_create)' '' e '' 'base.send (: embeds_many,: notifications,: as =>: notifiable)' '' nel mio modulo Notifiable. – genkilabs

+0

Come andresti a fare il send per dichiarare un scope in quel modulo? – Alex

+0

Ottengo "incluso": metodo "campo" non definito per Asset: Module (NoMethodError) '. Forse questo non funziona su Ruby 2.3.1? –

2

Ok, utilizzando le preoccupazioni rende questo molto più facile e più bello da scrivere:

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 

vedi http://api.rubyonrails.org/classes/ActiveSupport/Concern.html per maggiori dettagli.

Problemi correlati