【发布时间】:2017-11-24 21:40:34
【问题描述】:
我正在尝试创建一个新对象,其关联记录采用相同的形式,但希望关联记录使用find_or_create_by 而不仅仅是创建(因为关联的模型记录可能并且大部分时间已经存在)。在过去的两天里,我一直在挖掘与这个主题相关的每一篇文章和文章,试图让它发挥作用,但我的表单仍然试图只创建新对象,而不是搜索现有对象。
模型
#order.rb
has_many :order_owners, dependent: :destroy, inverse_of: :order
has_many :owners, through: :order_owners
accepts_nested_attributes_for :order_owners
#owner.rb
has_many :order_owners, dependent: :destroy
has_many :orders, through: :order_owners
validates :name, presence: true, uniqueness: { case_sensitive: false }
#order_owner.rb
belongs_to :owner
belongs_to :order
accepts_nested_attributes_for :owner
表格
orders/new.html.erb
<%= bootstrap_form_for(@orders, layout: :horizontal, label_col: "col-sm-2", control_col: "col-sm-6") do |f| %>
<%= render 'shared/error_messages', object: f.object %>
...
<%= f.fields_for :order_owners do |orderowner| %>
<%= render 'orders/new_order_owners', f: orderowner, render_partial: 'orders/new_order_owners' %>
<% end %>
...
<%= f.form_group do %>
<%= f.submit "Create Order", class: "btn btn-primary" %>
<%= link_to_add_association fa_icon("plus", text: "Add Owner"), f, :order_owners,
class: "btn btn-outline pull-right #{orderBtnDisable(@properties)}", partial: "orders/new_order_owners", id: "newOrderOwnerAdd" %>
<% end %>
<% end %>
orders/new_order_owners部分
<div class="m-t-md m-b-md border-bottom form-horizontal nested-fields">
<%= link_to_remove_association(fa_icon("remove", text: ""), f, { class: "btn btn-danger btn-outline pull-right" }) %>
<% f.object.build_owner unless f.object.owner %>
<%= f.fields_for :owner do |owner| %>
<%= owner.select :name, options_from_collection_for_select(@owners, "name", "name"),
{ label: "Name:", include_blank: true }, { id: "orderPropOwnerSelect", data: { placeholder: "Select an existing Owner or type a new one.."} } %>
<% end %>
</div>
控制器
orders/new
def new
@order = Order.new
@order.build_property
@order.order_owners.build.build_owner
@properties = Property.find_by_id(params[:property_id])
if @properties
@owners = @properties.owners
else
@owners = []
end
respond_to do |format|
format.html
format.js
end
end
orders/create
def create
@properties = Property.find(params[:order][:property_id])
@order = @properties.orders.create(order_params)
respond_to do |format|
format.html { if @order.save
if params[:order][:owners_attributes]
order_prop_owner_check(@order, @properties)
end
flash[:success] = "Order created successfully!"
redirect_to property_order_path(@properties, @order)
else
@properties
@owner = @properties.owner
render 'new'
end
}
format.js {
if @order.save
flash.now[:success] = "Order Updated Successfully!"
else
flash.now[:danger] = @order.errors.full_messages.join(", ")
end
}
end
end
正如您在new 操作中看到的那样,我实例化了新订单,构建了它的关联属性(它属于订单的所属对象),构建了新的 order_owner 关系,并为该关系构建了所有者。然后在提交时通过@properties.orders.create(order_params) 创建订单。
我得到的错误是“订单所有者所有者名称已存在”。很明显,它没有按名称查找所有者。 我试过了:
- 在 order.rb 和 order_owner.rb 中重新定义
autosave_associated_records_for_owner,同时使用 belongs_to 和 has_many 变体,但似乎它们从未被调用,所以我一定做错了什么。 (我已经尝试了几乎所有可以在 SO 上找到的答案的变体) -
before_add:在 order.rb 中对has_many :owners, through: :order_owners和has_many :order_owners进行回调。 - 在 order.rb 中扩展
has_many :owners和has_many :owners, through: :order_owners以及在 order_order.rb 中扩展belongs_to :owner
我还尝试了调用关联的不同变体等形式,所以我一定只是误解了一些东西。我也在使用 Cocoon 来管理嵌套表单,但我已经与作者讨论了不相关的问题,并且 Cocoon 本质上只是嵌套表单的视图助手,因此解决方案必须在模型/控制器中。
欢迎提出任何想法。提前致谢。
附:我在控制器动作中留下了可能/可能不属于这个确切帖子的代码,但我想展示整个动作的完整性。如果重要,当在另一个字段中选择属性时,我通过 AJAX 手动设置所有者选择。基本上它只是查找属性并将现有所有者添加到所有者选择中。
【问题讨论】:
-
确认一下,
OrderOwner表是连接表吗?也就是说,它真的只有订单的id和所有者的id吗?另外,你能添加你的路线吗? -
另外,对不起,如果我在这里很密集,但是你到底什么时候打电话给
.find_or_create_by? -
嘿,为延迟回复道歉,花了一整天的时间旅行。是的
OrderOwner是一个只有order_id和owner_id的连接表/模型。目前,我在任何时候都不会打电话给find_or_create_by,因为我无法让它工作。理想情况下,我希望在通过 Order 的嵌套属性创建所有者时调用它。从我发现的所有内容来看,OrderOwner 表中的autosave_associated_records_for_owner似乎(所以我认为)应该是我的票,但我无法让它发挥作用。我应该发布哪组路线?订单?
标签: ruby-on-rails ruby-on-rails-5 nested-forms nested-attributes