Reputation: 7490
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>
Upvotes: 5
Views: 767
Reputation: 34338
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
Upvotes: 5
Reputation: 35318
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.
Upvotes: 0
Reputation: 2599
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.
Upvotes: 0