2011-02-03 16 views
5

Tengo un módulo Blockable que contiene asociaciones y métodos para ser incluido en algunas otras clases de ActiveRecord.Rieles: ¿Cómo puedo definir una extensión de asociación en un módulo que se incluye en mi modelo AR?

código relevante:

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

Quiero agregar una extensión asociación. La sintaxis usual (es decir, cuando no estoy definiendo la asociación en un módulo) es la siguiente:

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

# usage 
Model.first.blocks.method_name 

Esta sintaxis no funciona cuando se utiliza en el módulo que se incluye en el modelo de AR. Obtengo un undefined method 'method_name' for #<ActiveRecord::Relation:0xa16b714>.

¿Alguna idea sobre cómo debo definir una extensión de asociación en un módulo para su inclusión en otras clases de AR?

+2

Su módulo se ve bien, parece que lo está llamando incorrectamente. 'Model.blocks' no debería funcionar. Lo está llamando a un objeto y no a una instancia de ese objeto. Pruebe 'Model.first.blocks.method_name'. –

+0

Lo siento, falla el ejemplo por mí. He estado intentando llamarlo en una instancia: he actualizado mi pregunta para solucionar esto. – nfm

Respuesta

2

Argh, apesta.

Tenía un error no relacionado que causaba la ruptura de la extensión de asociación.

He comprobado que tanto mi método original y método de trabajo de Xavier Holt debajo de los rieles 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

Tengo algo similar trabajando en mi código Rails (2.3.8) en este momento. Solía ​​base.class_eval en lugar de 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 

Uf - que era un montón de spacebarring ...

De todos modos, que funciona para mí - es de esperar que va a trabajar para usted, también!

+0

Gracias por el look-in y por darme otro método para probar. Resulta que lo arruiné en otro lado y ¡ambos enfoques funcionan! – nfm

7

Rails 3 tiene algunos métodos de ayuda para esto. Este ejemplo es de The Rails 3 Way, 2nd Edition:

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