轨道上的红宝石 - 参数顺序停止 *_attributes= 工作



所以我实施了一个黑客,我想知道什么是"正确"的方法。

问题是我有一个使用实例变量的*_attributes=()方法。这是一个问题的原因是,在调用该方法时,尚未设置该实例变量。这是有问题的方法:

def proposed_times_attributes=(attributes)
  attributes.each do |key,value|
    value[:timezone] = timezone
  end
  assign_nested_attributes_for_collection_association(:proposed_times, attributes)
end

时区在 proposed_times_attributes 之后的参数哈希中。因此,我的技巧是从参数中删除它,然后将其添加回来,从而将其移动到行尾。

def create
  p = params[:consultation]
  a = p.delete(:proposed_times_attributes)
  p[:proposed_times_attributes] = a
  @consultation = current_user.advised_consultations.new(p)
  ...
end

我应该这样做的正确方法是什么?

new()调用load()遍历每个键/值对的循环所在位置。

值得庆幸的是,我使用的是 Ruby 1.9.2 来保持顺序,但很高兴知道如何做到这一点,这样它就不会依赖于这个事实。

如果new之后的下一个操作始终是save操作,则可以将属性存储在访问器中,并根据需要使用before_validation回调对它们进行操作。

class Consultations < ActiveRecord::Base
  attr_accessor :proposed_times_attributes
  before_validation :assign_proposed_times
  def assign_proposed_times
    proposed_times_attributes.each do |key,value|
      value[:timezone] = timezone
    end
    assign_nested_attributes_for_collection_association(:proposed_times, attributes)
  end
end

现在,在您的控制器中,您只需拥有:

def create
  @consultation = current_user.advised_consultations.new(params[:consultation])
  ...
end

如果您希望在调用 save 之前执行其他操作,那么像在示例中所做的那样拉出参数,然后在调用 new 后将其传递给适当的方法将是要走的路。

相关内容

  • 没有找到相关文章

最新更新