我如何通过 activerecord 关联创建新对象

how do i create new objects through activerecord associations

我有一个 table 开关和快照。一个Switch有很多Snapshot,一个Snapshot属于一个Switch。我无法通过关联创建新的快照。在我的代码下面。

2.6.3 :014 > switch = Switch.new
 => #<Switch id: nil, switch: nil, ip_address: nil, created_at: nil, updated_at: nil> 
2.6.3 :015 > switch.create_snapshot
NoMethodError (undefined method `create_snapshot' for #<Switch:0x00000000039950e0>)

app/model

class Switch < ApplicationRecord

  has_many :snapshots

end

class Snapshot < ApplicationRecord

  belongs_to :switch

end

通过迁移配置的 psql

\d switches
Indexes:
    "switches_pkey" PRIMARY KEY, btree (id)
Referenced by:
    TABLE "snapshots" CONSTRAINT "fk_rails_5537742698" FOREIGN KEY (switch_id) REFERENCES switches(id)

# \d snapshots
Indexes:
    "snapshots_pkey" PRIMARY KEY, btree (id)
    "index_snapshots_on_switch_id" btree (switch_id)
Foreign-key constraints:
    "fk_rails_5537742698" FOREIGN KEY (switch_id) REFERENCES switches(id)

您需要在父模型上添加 accepts_nested_attributes_for :model

嵌套属性允许您通过父级保存关联记录的属性。默认情况下,嵌套属性更新是关闭的,您可以使用 #accepts_nested_attributes_for class 方法启用它。当您启用嵌套属性时,会在模型上定义一个属性编写器。 (来自 api.rubyonrails.org

首先创建交换机,之后您就可以像这样创建快照

switch = Switch.new 
switch.save
or
switch = Switch.create(switch_params)

然后

switch.snapshots.create(snapshot_params)

如果你想在创建开关的同时创建快照,那么你应该使用嵌套属性https://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

要一起创建关联对象,可以有这样的替代方法-

switch = Switch.new(swich_params)
switch.snapshots.build
switch.save

创建 switch 后,它还会创建关联的 snapshots