I have
class Fruit < ActiveRecord::Base
includes Skin
end
and the mixin module
module Skin
def initialize
self.skin = "fuzzy"
end
end
I want it so that
>> Fruit.new
#<Fruit skin: "fuzzy", created_at: nil, updated_at: nil>
Use the ActiveRecord after_initialize callback.
module Skin
def self.included(base)
base.after_initialize :skin_init
end
def skin_init
self.skin = ...
end
end
class Fruit < AR::Base
include Skin
...
end
Food::Fruitafter_initialize callback works a bit differently for Rails 3. Code updated now. Give it a try.#<Fruit skin: "fuzzy">. How do I make it so that create override the mixin's value?self.skin ||= "fuzzy". That should do the trick :)Try defining the reader/writer for skin instead:
module Skin
def skin
@skin||="fuzzy"
end
attr_writer :skin
end
class Fruit
include Skin
end
f=Fruit.new
puts f.skin # => fuzzy
f.skin="smooth"
puts f.skin # => smooth
Edit: for rails, you'd probably remove the attr_writer line and change @skin to self.skin or self[:skin], but I haven't tested this. It does assume that you'll access skin first in order to set it, but you could get around this by coupling it with a default value in the database. There's probably a rails specific callback that will provide a simpler solution.
I think you just need to call super before you make any adjustments:
module Skin
def initialize(*)
super
self.skin = "fuzzy"
end
end
class Fruit < ActiveRecord::Base
include Skin
end
Untested.
initialize on ActiveRecord objects. Rails does not guarantee initialize is called in all situations. See here: blog.dalethatcher.com/2008/03/…