在Rails中,update_attributes的反转是什么?

z5h*_*z5h 6 ruby activerecord ruby-on-rails

在Rails中,反过来是什么update_attributes!

换句话说,什么将记录映射到将重新创建该记录及其所有子记录的属性哈希?

答案并非ActiveRecord.attributes如此,因为它不会递归到子对象中.

澄清您是否有以下内容:

class Foo < ActiveRecord::Base
  has_many :bars
  accepts_nested_attributes_for :bars
end
Run Code Online (Sandbox Code Playgroud)

然后你就可以传递哈希了

{"name" => "a foo", "bars_attributes" => [{"name" => "a bar} ...]}

update_attributes.但目前尚不清楚如何以编程方式为此目的轻松生成此类哈希.

编辑:
正如我在评论中提到的,我可以这样做:
foo.as_json(:include => :bars)

但我想要一个使用accepts_nested_attributes_for :bars声明的解决方案,以避免必须明确包含关联.

oma*_*ous 1

不知道这会是怎样的“逆”,但是虽然 Rails 可能没有“有答案”,但没有什么可以阻止你遍历一个对象并非常有效地创建它。

一些可以帮助您入门的东西:

http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html#method-i-accepts_nested_attributes_for

您会注意到,在该accepts_nested_attributes_for方法中,rails 为 中嵌套的所有模型设置了哈希值nested_attributes_options。因此,我们可以使用它来获取这些嵌套关联,以填充这个新的哈希值。

def to_nested_hash
  nested_hash = self.attributes.delete_if {|key, value| [:id, :created_at, :deleted_at].include? key.to_sym } # And any other attributes you don't want

  associations = self.nested_attributes_options.keys
  associations.each do |association|
    key = "#{association}_attributes"
    nested_hash[key] = []
    self.send(association).find_each do |child|
      nested_hash[key] << child.attributes.delete_if {|key, value| [:id, :created_at, :deleted_at].include? key.to_sym }
    end
  end

  return nested_hash
end
Run Code Online (Sandbox Code Playgroud)

或者只是想到了这个:

使用上面的例子:

foo.as_json(:include => foo.nested_attributes_options.keys)
Run Code Online (Sandbox Code Playgroud)

需要注意的一件事是,这不会为您提供bars_attributes我的第一个建议所提供的信息。(也不会serializable_hash