tl;dr:这将满足您的需要:
report = Report.first
dosage = report.dosages.build
report.dosages.size // 1
to_delete_dosage = report.dosages.first
report.dosages.delete(to_delete_dosage)
report.dosages.size // 0
有关详细信息,请查看文档
ActiveRecord_Associations_CollectionProxy::delete
第一,
ActiveRecord::Relation#build
是的别名
ActiveRecord::Relation#new
:
可以将新对象实例化为空对象(不传递构造参数)或具有属性但尚未保存的预设对象(传递具有匹配关联表列名的键名的哈希)。在这两种情况下,有效的属性键都是由关联表的列名决定的,因此不能有不属于表列的属性。
如果希望删除第一个元素,则必须将其持久化到数据库中,否则Rails将完全按照您的经验进行操作,请设置destroyed标志。
尝试以下顺序:
report = Report.first
dosage = report.dosages.build
dosage.save
report.dosages.size # 1
report.dosages.first.destroy
report.dosages.size # 0
我设置了与您的问题等效的输出:
您的方案:
2.4.0 :007 > r.dosages.build
=> #<Dosage id: nil, title: nil, created_at: nil, updated_at: nil, report_id: 1>
2.4.0 :008 > r.dosages.size
=> 1
2.4.0 :009 > r.dosages.first.destroy
(0.1ms) begin transaction
(0.0ms) commit transaction
=> #<Dosage id: nil, title: nil, created_at: nil, updated_at: nil, report_id: 1>
2.4.0 :010 > r.dosages.size
=> 1
我的建议:
2.4.0 :005 > report = Report.first
Report Load (0.1ms) SELECT "reports".* FROM "reports" ORDER BY "reports"."id" ASC LIMIT ? [["LIMIT", 1]]
=> #<Report id: 1, title: nil, date: nil, created_at: "2018-07-03 14:00:08", updated_at: "2018-07-03 14:00:08">
2.4.0 :006 > report.dosages.count
(0.1ms) SELECT COUNT(*) FROM "dosages" WHERE "dosages"."report_id" = ? [["report_id", 1]]
=> 0
2.4.0 :007 > dosage = report.dosages.build
=> #<Dosage id: nil, title: nil, created_at: nil, updated_at: nil, report_id: 1>
2.4.0 :008 > dosage.save
(0.1ms) begin transaction
SQL (0.7ms) INSERT INTO "dosages" ("created_at", "updated_at", "report_id") VALUES (?, ?, ?) [["created_at", "2018-07-03 14:06:08.709323"], ["updated_at", "2018-07-03 14:06:08.709323"], ["report_id", 1]]
(0.9ms) commit transaction
=> true
2.4.0 :009 > report.dosages.size
(0.2ms) SELECT COUNT(*) FROM "dosages" WHERE "dosages"."report_id" = ? [["report_id", 1]]
=> 1
2.4.0 :010 > report.dosages.first.destroy
Dosage Load (0.2ms) SELECT "dosages".* FROM "dosages" WHERE "dosages"."report_id" = ? ORDER BY "dosages"."id" ASC LIMIT ? [["report_id", 1], ["LIMIT", 1]]
(0.0ms) begin transaction
SQL (0.3ms) DELETE FROM "dosages" WHERE "dosages"."id" = ? [["id", 1]]
(0.8ms) commit transaction
=> #<Dosage id: 1, title: nil, created_at: "2018-07-03 14:06:08", updated_at: "2018-07-03 14:06:08", report_id: 1>
2.4.0 :011 > report.dosages.size
(0.2ms) SELECT COUNT(*) FROM "dosages" WHERE "dosages"."report_id" = ? [["report_id", 1]]
=> 0
我相信这就是你需要的。关系设置如下:
dosage.rb
class Dosage < ApplicationRecord
belongs_to :report
end
report.rb
class Report < ApplicationRecord
has_many :dosages
end
以及以下迁移:
class ManyDosagesToReport < ActiveRecord::Migration[5.0]
def change
add_column :dosages, :report_id, :integer
end
end
事实上,如果你试图坚持
dosage
对象是您构建的,但没有坚持,Rails会抱怨:
RuntimeError: can't modify frozen Hash
由于
destroyed
属性。