我有一个'gin‘模型,允许嵌套属性’名称‘在’酒厂‘模型。嵌套表单运行良好,但我意识到我正在创建“复制”酒厂条目。看来'find_or_create_by‘应该可以防止这一点,,但我不能让它不创建一个副本.
因为这是一个嵌套的表单,所以我也不确定应该放置哪个控制器。
这是我到目前为止所拥有的,正如前面提到的,这将继续为一家酿酒厂创造多种记录。我没有任何错误。
gins_controller.rb
class GinsController < ApplicationController
...
def new
@gin = Gin.new
@gin.build_distillery
enddistillery_controller.rb
class DistilleriesController < ApplicationController
...
def new
@distillery = Distillery.find_or_create_by(name: 'name')
endgins_form
<%= form.fields_for :distillery do |distillery_form| %>
<p>
<%= distillery_form.label :distillery, class: "block text-grey-darker text-sm font-bold mb-2" %>
<%= distillery_form.text_field :name, class:"lg:w-2/5 w-full shadow appearance-none border rounded py-2 px-3 mb-6 text-grey-darker" %>
</p>
<% end %>更新
已经将它移到gins_controller中,但它没有解决这个问题:
def new
@gin = Gin.new
@gin.build_distillery
@distillery = Distillery.find_or_create_by(name: 'name')
end发布于 2018-03-06 01:53:09
new方法用于创建要显示在视图中的新对象(用于输入数据以在数据库中创建记录的表单)。但是new方法没有将对象保存到数据库中。因此,在find_or_create方法中使用new方法是没有意义的。只需使用新或build即可。
您应该在create方法中使用,在该方法中,记录实际上是创建一个保存的。
另一种方法是将酿酒厂名称定义为一个独特的字段,因此不能创建重复的酿酒厂。
第三种选择是使用select字段以形式选择酒厂(这要求在创建杜松子酒之前创建酿酒厂)。一般来说,这应该是最好的方法:如果Gin belongs_to :蒸馏器(我假设),最好选择酿酒厂,而不是在字段中输入名称。如果您做了一个错误,您将创建一个新的酿酒厂,而不是使用一个现有的。
发布于 2018-03-06 03:40:53
我同意巴勃罗的看法。下面是如何实现新/创建方法的一个想法--如果您想让大部分代码保持不变
def new
@gin = Gin.new
@gin.build_distillery
end
def create
@gin = Gin.new(gin_params)
@gin.distillery = Distillery.find_or_create_by(name: distillery_name)
@gin.save! # oversimplification - you probably have respond blocks
end
def distillery_name
params[:distillery][:name] # or however it really is
end发布于 2018-03-18 10:46:28
由于您没有具体说明这一点,我假设您的协会如下所示:
class Gin
belongs_to :distillery
class Distillery
has_many :gins 一般来说,在这种情况下,你要做的就是从下拉列表中选择一个酿酒厂。因此,我们将直接设置链接(distillery_id),因此在模型Gin中不需要accepts_nested_attributes_for。
如果您使用的是简单形式的宝石,这就像使用简单的宝石一样简单。
f.association :distillery 或者使用普通形式,您可以编写如下内容
f.collection_select :distillery_id, Distillery.all, :id, :name, {include_blank: true}到目前为止,您不需要在控制器端做任何特别的事情:当保存表单时,它会设置酿酒厂id,这将创建链接。但它也假设酿酒厂已经存在(在大多数情况下都是如此)。
当你想要连接到一个现有的酒厂或者以一种形式创建一个新的酒厂时,它会变得更加复杂。
要解决这个问题,一个非常简单的解决方案是按以下方式编写表单:
= f.collection_select :distillery_id, Distillery.all, :id, :name, {include_blank: true}
= text_field_tag :distillery_name (为了获得最佳的用户体验,您可以添加一些js,以确保用户要么从下拉列表中选择什么,要么填写名称)。
然后在你的控制器里你可以做一些类似的事情
def create
if params[:gin][:distillery_id].blank? && params[:distillery_name].present?
@distillery = Distillery.find_or_create_by(name: params[:distillery_name])
params[:gin][:distillery_id] = @distillery.id
end
gin = Gin.build(gin_params)
[... the rest of your create method as before ...]因此,简而言之:
https://stackoverflow.com/questions/49118664
复制相似问题