5

Ho un modulo di Blockable che contiene le associazioni ed i metodi da includere in un paio di altri ActiveRecord classi.Rails: come si definisce un'estensione di associazione in un modulo che viene incluso nel mio modello AR?

codice rilevante:

module Blockable 
    def self.included(base) 
    base.has_many :blocks 
    end 
end 

voglio aggiungere un'estensione associazione. La sintassi solito (cioè quando non sto definendo l'associazione in un modulo) è come questo:

# definition in Model < ActiveRecord::Base 
has_many :blocks do 
    def method_name 
    ... code ... 
    end 
end 

# usage 
Model.first.blocks.method_name 

Questa sintassi non funziona quando viene utilizzato nel modulo che è incluso nel modello AR. Ottengo un undefined method 'method_name' for #<ActiveRecord::Relation:0xa16b714>.

Qualsiasi idea di come dovrei andare sulla definizione un'estensione associazione in un modulo per l'inclusione in altre classi AR?

+2

Il modulo guarda bene, sembra proprio come si sta chiamando in modo errato. 'Model.blocks' non dovrebbe funzionare. Lo stai chiamando su un oggetto e non su un'istanza di quell'oggetto. Provare 'Model.first.blocks.method_name'. –

+0

Mi dispiace, non riesco ad esempio da me. Ho provato a chiamarlo su un'istanza: ho aggiornato la mia domanda per risolvere il problema. – nfm

risposta

2

Argh, faccio schifo.

ho avuto un bug che causava non correlato l'estensione dell'associazione di rompere.

Ho verificato che sia il mio metodo originale e il metodo di lavoro di Xavier Holt in Rails 3.0.3:

self.included(base) 
    base.has_many :blocks do 
    def method 
     ... 
    end 
    end 
end 

# OR 

self.included(base) 
    base.class_eval do 
    has_many :blocks do 
     def method 
     ... 
     end 
    end 
    end 
end 
4

ho qualcosa di lavoro simile nel mio codice Rails (2.3.8) in questo momento. Ho usato base.class_eval piuttosto che base.has_many:

module Blockable 
    self.included(base) 
     base.class_eval do 
      has_many :blocks do 
       def method_name 
        # ...stuff... 
       end 
      end 
     end 
    end 
end 

Wow - che era un sacco di spacebarring ...

In ogni caso, che funziona per me - spero che funzionerà anche per te!

+0

Grazie per la ricerca e dandomi un altro metodo per provare. Si scopre che mi sono fottuto altrove e che entrambi gli approcci funzionano! – nfm

7

Rails 3 ha alcuni metodi di supporto per questo. Questo esempio è da The Rails 3 Way, 2nd Edition:

module Commentable 
    extend ActiveSupport::Concern 
    included do 
    has_many :comments, :as => :commentable 
    end 
end