Skip to content

Instantly share code, notes, and snippets.

@linjunpop
Created September 13, 2012 09:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save linjunpop/3713094 to your computer and use it in GitHub Desktop.
Save linjunpop/3713094 to your computer and use it in GitHub Desktop.
metadata fields
>> p = Product.create(:name => 'p1', :foobar => true)
>> p.name
=> "p1"
>> p.foobar
=> true
module MetaField
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def meta_field(field, options={})
type = options.fetch(:type, String)
required = options.fetch(:required, false)
default = options.fetch(:default, nil)
self.send(:validates_presence_of, field) if required
define_method field do
self.metadata[field]
end
define_method "#{field}=" do |value|
self.metadata[field] = Kernel.const_get(type.to_s.classify).new(value || default)
end
end
end
def metadata
self.read_attribute(:metadata) || {}
end
end
class Product < ActiveRecord::Base
serialize :metadata, Hash
include MetaField
meta_field :name, :type => String
meta_field :foobar, :type => Boolean, :required => true
end
create_table "products", :force => true do |t|
t.text "metadata"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment