Módulo de rieles con Mongoid

I'm trying to extend a few of my model classes to an "Asset" class. Each of the four types of Assets will be able to generate a slug off a set_callback(:save, :before) Consequently, instead of writing four methods that are the same, I'd like them to extend an Asset class that would have the set_callback (as well as other methods).

At first I tried simply having them extend the Asset class but I ran into problems where when I saved one of the assets to the database (mongo), the collection they inserted into was called Asset rather than their own name.

After I googled around people seem to recommend using modules instead. So I've tried that:

module Asset
  field :slug, :type => String

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

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

But I get some errors when I include Asset:

'undefined method `field' for Asset:Module'

Note: I'm using Mongoid

preguntado el 09 de marzo de 12 a las 17:03

2 Respuestas

The method field is not known in the context of the Asset module. So you have to call field only when the module is included:

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

Edit: wrapped code in code block

respondido 27 mar '13, 18:03

Thanks, worked great for me. Also used base.send(:before_create, :notify_on_create) y base.send(:embeds_many, :notifications, :as => :notifiable) in my Notifiable module. - genkilabs

How would you go do the send to declare a scope in that module ? - Alex

yo obtengo included': undefined method field' for Asset:Module (NoMethodError)`. Perhaps this does not work on Ruby 2.3.1? - B siete

Ok, using concerns makes this much much easier and nicer to write:

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

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

Respondido el 09 de diciembre de 13 a las 15:12

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.