2012-03-09 13 views
5

Estoy tratando de extender algunas de mis clases de modelo a una clase de "Activo". Cada uno de los cuatro tipos de activos será capaz de generar una babosa en set_callback(:save, :before) En consecuencia, en lugar de escribir cuatro métodos que son iguales, me gustaría que amplíen una clase de activo que tendría el set_callback (así como otros métodos).Módulo de rieles con Mongoid

Al principio intenté simplemente extender la clase de activo pero me encontré con problemas donde cuando guardé uno de los activos en la base de datos (mongo), la colección en la que insertaban se llamaba Asset en lugar de su propio nombre.

Después de buscar en Google, las personas parecen recomendar el uso de módulos en su lugar. Así que he intentado:

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 

Pero consigo algunos errores cuando incluyo Activos:

'undefined method `field' for Asset:Module' 

Nota: Estoy usando Mongoid

Respuesta

7

El campo método no es conocido en el contexto del módulo de activos. Así que hay que llamar al campo sólo cuando se incluye el módulo:

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

Editar: Código envuelto en bloque de código

+0

Gracias, funcionó muy bien para mí. También se usa '' 'base.send (: before_create,: notify_on_create)' '' y '' 'base.send (: embeds_many,: notificaciones,: as =>: notificables)' '' en mi módulo Notifiable. – genkilabs

+0

¿Cómo harías el envío para declarar un alcance en ese módulo? – Alex

+0

Me sale 'incluido ': método indefinido' field' para Asset: Module (NoMethodError) '. Quizás esto no funciona en Ruby 2.3.1? –

2

Ok, utilizando preocupaciones hace esto mucho más fácil y más agradable para escribir:

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 

ver http://api.rubyonrails.org/classes/ActiveSupport/Concern.html para más detalles.

Cuestiones relacionadas