如何使用 ActiveModel 在一次交易中保存 2 个模型?
How to save 2 models in one transaction using ActiveModel?
我有一个小 class 可以与 4 个模型一起使用。我想以“正确”的方式做事。基本上,我想创建 2 个 Address
模型,1 个 Shipment
(w/2 address_ids,和属于 Shipment
.
的 1 Parcel
在这一点上,我很困惑。我需要克服这一点,进入下一个重要的里程碑。这看起来有前途吗,还是您建议在控制器中保存 2 条记录,然后使用 after_create 或类似的东西?谢谢。
class Quote
include ActiveModel::Model
attr_accessor address_to: {
:name, :company, :street1, :street2, :street3, :city, :state,
:zip, :country, :phone, :email},
address_from: {
:name, :company, :street1, :street2, :street3, :city, :state,
:zip, :country, :phone, :email
}
def save
return false if invalid?
ActiveRecord::Base.transaction do
user = User.find_by(id: user_id)
user.addresses.create!([{address_from, address_to}]) # how to do this?
end
end
end
如果您通过标签 :belongs_to
和 :has_many
使用模型关联,
例如,您可以使用 accepts_nested_attributes_for :another_child_model
。如果您在控制器上允许这些参数,它将自动创建或定义此关联。
Rails guide for nested attributes
注意在控制器上允许这些属性。
class YourController < ApplicationController
...
def your_params
params.require(:entity).permit(:etc, :etc, child_model_attributes: [:id, :name, :etc, :etc])
end
...
end
- 切勿在模型上使用回调。难以测试模型,不可预测的行为。
- 你可以使用 accept_nested_attributes.
- 如果您有自定义逻辑,您可以使用服务对象模式并将所有逻辑放在那里。
但是如果你想像你那样做然后尝试使用
user.addresses.create!([address_from, address_to])
如果您使用的是 Rails 6
或更高版本 - 有一种名为 insert_all
的方法可以在一条 INSERT
语句中将多条记录插入数据库。
在 apidock 上查看:insert_all
示例:
Book.insert_all([
{ id: 1, title: "Rework", author: "David" },
{ id: 1, title: "Eloquent Ruby", author: "Russ" }
])
(来自文档的示例)
我有一个小 class 可以与 4 个模型一起使用。我想以“正确”的方式做事。基本上,我想创建 2 个 Address
模型,1 个 Shipment
(w/2 address_ids,和属于 Shipment
.
1 Parcel
在这一点上,我很困惑。我需要克服这一点,进入下一个重要的里程碑。这看起来有前途吗,还是您建议在控制器中保存 2 条记录,然后使用 after_create 或类似的东西?谢谢。
class Quote
include ActiveModel::Model
attr_accessor address_to: {
:name, :company, :street1, :street2, :street3, :city, :state,
:zip, :country, :phone, :email},
address_from: {
:name, :company, :street1, :street2, :street3, :city, :state,
:zip, :country, :phone, :email
}
def save
return false if invalid?
ActiveRecord::Base.transaction do
user = User.find_by(id: user_id)
user.addresses.create!([{address_from, address_to}]) # how to do this?
end
end
end
如果您通过标签 :belongs_to
和 :has_many
使用模型关联,
例如,您可以使用 accepts_nested_attributes_for :another_child_model
。如果您在控制器上允许这些参数,它将自动创建或定义此关联。
Rails guide for nested attributes
注意在控制器上允许这些属性。
class YourController < ApplicationController
...
def your_params
params.require(:entity).permit(:etc, :etc, child_model_attributes: [:id, :name, :etc, :etc])
end
...
end
- 切勿在模型上使用回调。难以测试模型,不可预测的行为。
- 你可以使用 accept_nested_attributes.
- 如果您有自定义逻辑,您可以使用服务对象模式并将所有逻辑放在那里。
但是如果你想像你那样做然后尝试使用
user.addresses.create!([address_from, address_to])
如果您使用的是 Rails 6
或更高版本 - 有一种名为 insert_all
的方法可以在一条 INSERT
语句中将多条记录插入数据库。
在 apidock 上查看:insert_all
示例:
Book.insert_all([
{ id: 1, title: "Rework", author: "David" },
{ id: 1, title: "Eloquent Ruby", author: "Russ" }
])
(来自文档的示例)