axsuul
axsuul

Reputation: 7490

Using mixins to initialize class variables

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

Answers (3)

Casper
Casper

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

d11wtq
d11wtq

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

Tapio Saarinen
Tapio Saarinen

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

Related Questions