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
  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
But I get some errors when I include Asset:
'undefined method `field' for Asset:Module'
Note: I'm using Mongoid
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)
    end
  end
Edit: wrapped code in code block
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) }
  end
 end
end
see http://api.rubyonrails.org/classes/ActiveSupport/Concern.html for more details.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With