【问题标题】:ActiveRecord custom attributes used in rails 3 not working in rails 4Rails 3 中使用的 ActiveRecord 自定义属性在 rails 4 中不起作用
【发布时间】:2015-01-09 10:41:02
【问题描述】:

我在 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 对象访问 custom 列。

但我们正计划升级到 rails 4,但它无法在那里工作。除了使用 attr_accessor 之外,还有什么解决方法吗??

【问题讨论】:

  • 使用write_attribute
  • 谢谢@MarekLipka 有什么例子吗?也请通过下面的评论。
  • 示例:cart_obj.write_attribute('custom', 1).

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


【解决方案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

【讨论】:

    【解决方案2】:

    在 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
    

    【讨论】:

    • 感谢@Ajay 的快速回复。但除了使用 attr_accesor 之外,我正在寻找其他解决方法。
    • 目的是什么,我会尽我所能。 :)
    • 我们在 rails 3.2 中有一个大型项目,我们想将它升级到 rails 4.2。因此,正如我在示例代码中提到的,我们有大量的自定义属性。如果我们开始将它用作 attr_accessor,那么将花费太多时间,这是不可行的。因此,最初我们希望以某种方式使其处于工作状态,然后按照您提到的方式继续改进。
    猜你喜欢
    • 2013-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    • 2012-06-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多