Rails:ActiveRecord相互依赖的属性设置器

时间:2013-11-27 18:39:43

标签: ruby-on-rails ruby activerecord

在activerecord中,似乎按照param哈希的顺序调用属性setter。 因此,在下面的示例中,“par_prio”在“par1”setter中将为空。

class MyModel < ActiveRecord::Base
  def par1=(value)
    Rails.logger.info("second param: #{self.par_prio}")
    super(value)
  end
end

MyModel.new({ :par1 => 'bla', :par_prio => 'bouh' })

有没有办法简单地在模型中定义属性的顺序?

2 个答案:

答案 0 :(得分:0)

注意:我有一个解决方案,但不是&#34; generic&#34;,通过覆盖&#34; MyModel&#34;上的初始化方法:

def initialize(attributes = {}, options = {})
  if attributes[:par_prio]
    value = attributes.delete(:par_prio)
    attributes = { :par_prio => value }.merge(attributes)
  end
  super(attributes, options)
end

此外,如果par_prio是另一个具有关系的模型,并且用于构建MyModel,则它不起作用:

class ParPrio < ActiveRecord::Base
  has_many my_models
end

par_prio = ParPrio.create
par_prio.my_models.build(:par1 => 'blah')

par_prio参数在初始化覆盖中不可用。

答案 1 :(得分:0)

覆盖特定模型上的assign_attributes,您需要按特定顺序进行分配:

    attr_accessor :first_attr  # Attr that needs to be assigned first
    attr_accessor :second_attr # Attr that needs to be assigned second

    def assign_attributes(new_attributes, options = {})
      sorted_new_attributes = new_attributes.with_indifferent_access
      if sorted_new_attributes.has_key?(:second_attr)
        first_attr_val = sorted_new_attributes.delete :first_attr
        raise ArgumentError.new('YourModel#assign_attributes :: second_attr assigned without first_attr') unless first_attr_val.present?
        new_attributes = Hash[:first_attr, first_attr_val].merge(sorted_new_attributes)
      end
      super(new_attributes, options = {})
    end