简体   繁体   中英

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>

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM