我的同事和我注意到一些关于ActiveRecord has_one
关联的事情,这些关联感觉错误/危险并且似乎不容易记录。
假设我们有这个设置:
class User < ApplicationRecord
has_one :subscription
end
class Subscription < ApplicationRecord
belongs_to :user
end
> user = User.create(name: "Bob")
> user.subscription = Subscription.create(provider: "Stripe")
> user.subscription = nil
(0.1ms) begin transaction
SQL (0.4ms) UPDATE "subscriptions" SET "user_id" = ?, "updated_at" = ? WHERE "subscriptions"."id" = ? [["user_id", nil], ["updated_at", 2017-01-10 19:24:56 UTC], ["id", 2]]
(2.0ms) commit transaction
class User < ApplicationRecord
has_one :subscription, dependent: :destroy
end
> user = User.create(name: "Bob")
> user.subscription = Subscription.create(provider: "Stripe")
> user.subscription = nil
(0.1ms) begin transaction
SQL (1.1ms) DELETE FROM "subscriptions" WHERE "subscriptions"."id" = ? [["id", 1]]
(0.7ms) commit transaction
这是预期的行为吗?我真的很惊讶,在没有显式调用save
或destroy
或update
等情况下完成了SQL调用。我也对dependant: destroy
改变行为的原因感到困惑在这种情况下。
这应该发生,如果是这样,它是否记录在任何地方? dependant: destroy
版本似乎特别危险。
这是使用Rails 5以及几个版本的Rails 4测试的。
答案 0 :(得分:2)
来自guide:
4.2.5何时保存对象?
将对象分配给has_one关联时,该对象为 自动保存(以更新其外键)。此外, 任何被替换的对象也会自动保存,因为它 外键也会改变。
如果这些保存中的任何一个由于验证错误而失败,那么 赋值语句返回false,赋值本身就是 取消。
如果父对象(声明has_one关联的对象)是 未保存(即new_record?返回true)然后是子对象 没有保存。它们将在保存父对象时自动生成。
如果要在没有的情况下将对象分配给has_one关联 保存对象,使用association.build方法。
答案 1 :(得分:1)
这是预期的行为吗?
是。 Rails docs on has_one
associations:
帐户#受益人=(受益人)(类似于beneficiary.account_id = 帐户ID; beneficiary.save)
至于dependent: :destroy
,来自相同的文档:
:destroy导致关联对象也被销毁
因此SQL DELETE
查询。