ActiveRecord custom attributes used in rails 3 do not work in rails 4

I have the following code working in 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

      

And I can access the custom column from the cart_obj object whenever we need it.

But we are planning to switch to rails 4 and not work there. Is there any work around for it other than using attr_accessor ??

+3


source to share


2 answers


On rails 4, use attr_accessor:

If you have additional instance data you don't have to persist (i.e. it's not a database column), you can use attr_accessor to save multiple lines of code.



class cart < ActiveRecord::Base
  attr_accessor  :custom

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

      

0


source


It looks like the monkey fix is ​​your way to go:

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

      



Or if you want this to be a problem:

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


source







All Articles