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