在rails 3中使用的ActiveRecord自定义属性不在rails 4中工作

时间:2015-01-09 10:41:02

标签: ruby-on-rails ruby-on-rails-4 activerecord attributes ruby-on-rails-3.2

我在rails 3.2中使用以下代码:

class Cart < ActiveRecord::Base
  def self.get_details()
    cart_obj = Cart.first
    cart_obj["custom"] = 1 #Here *custom* is not the column in database
  end
end

我可以随时从cart_obj对象访问自定义列。

但是我们计划升级到rails 4并且它不在那里工作。除了使用attr_accessor ??

之外,还有其他解决方法吗?

2 个答案:

答案 0 :(得分:1)

听起来像猴子补丁是你要走的路:

class ActiveRecord::Base
  def [](key)
    return super(key) if self.class.column_names.include?(key.to_sym)
    self.class.send :attr_accessor, key.to_sym unless self.class.instance_variable_defined?("@#{key}".to_sym)
    self.instance_variable_get("@#{key}".to_sym)
  end

  def []=(key, val)
    return super(key, val) if self.class.column_names.include?(key.to_sym)
    self.class.send :attr_accessor, key.to_sym unless self.class.instance_variable_defined?("@#{key}".to_sym)
    self.instance_variable_set("@#{key}".to_sym, val)
  end
end

或者,如果您想将其作为一个问题:

module MemoryStorage
  extend ActiveSupport::Concern
  def [](key)
    return super(key) if self.class.column_names.include?(key.to_sym)
    self.class.send :attr_accessor, key.to_sym unless self.class.instance_variable_defined?("@#{key}".to_sym)
    self.instance_variable_get("@#{key}".to_sym)
  end

  def []=(key, val)
    return super(key, val) if self.class.column_names.include?(key.to_sym)
    self.class.send :attr_accessor, key.to_sym unless self.class.instance_variable_defined?("@#{key}".to_sym)
    self.instance_variable_set("@#{key}".to_sym, val)
  end
end

class Cart < ActiveRecord::Base
  include MemoryStorage

  def self.get_details()
    cart_obj = Cart.first
    cart_obj.db_column = 'direct DB access'
    cart_obj["custom"] = 'access to "in-memory" column'
  end
end

答案 1 :(得分:0)

在rails 4中,使用attr_accessor:

如果你有其他实例数据,你不需要持久化(即它不是数据库列),那么你可以使用attr_accessor来保存几行代码。

class cart < ActiveRecord::Base
  attr_accessor  :custom

  def self.get_details
    cart_obj = Cart.first
    cart_obj.custom = whatever 
  end
end