ActiveRecord保存对父保存的has_many子项的所有更改

时间:2017-03-15 11:50:53

标签: ruby-on-rails ruby rails-activerecord

我尝试更新父对象(Client)和关联的子对象(License)。这些对象中的任何一个都可能是新的,这就是为什么我必须检查要更新的现有对象的原因,以及我是否还要创建它们。

我的代码目前看起来像这样:

return nil unless params.has_key?('client_uid')
client = Client.find_by_uid(params['client_uid'])
if client.nil?
  client = Client.new(uid: params['client_uid'])
end
client.app = params['application']
client.app_version = params['application_version']
...

licenses = params['licenses']
licenses.each do |licenseInfo|
  next unless licenseInfo.has_key?('application')
  license = client.licenses.find_by_application(licenseInfo['application'])
  if license.nil?
    license = License.new
    # add license without instantly saving
    client.association(:licenses).add_to_target(license)
    license.application = licenseInfo['application']
  end
  license.options = licenseInfo['options']
  ...
end
client.last_seen = Time.zone.now
client.save

这可以创建新客户端并从params中的值更新现有客户端,以及为客户端添加新许可证(我将在以后实施删除旧许可证)。问题是,当我致电client.save时,不会保存对现有许可的更改。

我不确定我是否做错了什么,或者ActiveRecord是否真的无法处理这样的情况。我已经搜索过此问题并尝试为autosave: true类明确指定License' belongs_to按照建议here,但这没有任何效果。

总之,我的问题是:我需要更改哪些内容才能将Client与所有更改(新增,更改,删除)一起保存到licenses

编辑: 我尝试手动保存所有许可证并将其放在一个事务中:

Client.transaction do
  client.save
  client.licenses.each do |license|
    license.save
  end
end

但这也没有奏效。现在我很困惑......

1 个答案:

答案 0 :(得分:1)

我认为你需要添加

accepts_nested_attributes_for :licenses
客户端模型中的

。这有助于您保存子对象

如评论中所述。请参阅此链接

http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html