我已经查看了类似问题的各种答案,并没有完全破解它。
wine
模型定义为has_one :register, :dependent => :destroy
,正确或错误地添加了accepts_nested_attributes_for :register
。 register
定义为belongs_to :wine
。
wines_controller.rb
create
内的代码为:
def new
@wine = Wine.new
@register = Register.new
def create
@wine = Wine.new(wine_params)
@register = @wine.registers.build(register_params)
respond_to do |format|
if @wine.save
#success
else
format.json { render json: @wine.errors, status: :unprocessable_entity }
format.json { render json: @register.errors, status: :unprocessable_entity }
end
end
end
我创建new wine
的表单包含以下代码:
<%= simple_form_for @wine do |f| %>
# various working elements
<div class="field">
<% f.fields_for :register do |r| %>
<%= r.label :short_name %>
<%= r.text_field :short_name %>
<%= r.label :barcode %>
<%= r.text_field :barcode %>
<% end %>
</div>
当调用此表单时,不会从f.fields_for
命令创建任何字段,但会执行此块,因为我可以在其中添加测试按钮以证明它已被访问。
如果我尝试创建葡萄酒,我会收到以下错误消息:
undefined method `registers' for #<Wine:0x007f1204375330> Did you mean? register register= register_id
我认为使用.build
确保数据完整性:我不想创建没有相应wine
的{{1}}。我已经尝试过考虑它的嵌套属性,但这似乎被许多人认为是一个糟糕的计划。这种当前的方法感觉正确,但我认为我至少缺少对语法的一些理解。
日后,有必要将与register
相关联的其他模型与葡萄酒无关。我正在考虑类似的方法,但我很高兴被告知重新考虑!
答案 0 :(得分:2)
如果我理解正确,你有2个问题:
首先,未显示注册字段 - 部分原因是@ wine.register为零。
您应该将新操作更改为:
def new
@wine = Wine.new
@wine.register = Register.new
此外,由于您使用的是simple_form_for
,因此您需要使用simple_fields_for
代替fields_for
导致异常的第二个问题告诉你一切......你正试图访问@ wine.registers,而不是@ wine.register
将创建方法更改为:
@register = @wine.register.build(register_params)
这将解决这个问题......但是......你真正需要做的就是从params构建@wine对象 - 你的params应该被配置为允许正确的嵌套属性 - 如果它设置正确的话在构建@wine对象时也将构建register对象。
您的模型已设置为accept_nested_attributes,因此在调用@ wine.save时也将验证并保存寄存器对象 - 无需显式保存寄存器对象。
你应该有类似的东西:
def wine_params
params.require(:wine).permit(
:attribute1, :attribute2,
register_attributes: [:id, :short_name, :barcode])
end
答案 1 :(得分:0)
试试这个
葡萄酒和注册模型
class Wine < ApplicationRecord
has_one :register, inverse_of: :wine, :dependent => :destroy
accepts_nested_attributes_for :register
end
class Register < ApplicationRecord
belongs_to :wine, inverse_of: :register
validates_presence_of :wine
end
葡萄酒控制器
class WinesController < ApplicationController
def new
@wine = Wine.new
@wine.build_register
end
def create
@wine = Wine.new(wine_params)
if @wine.save
redirect_to @wine
else
render :new
end
end
private
def wine_params
params.require(:wine).permit(:name, register_attributes: [:simple_name])
end
end
我的wine_params特定于
rails g model wine name:string
rails g model register name:string wine_id:integer
最后,葡萄酒形式应如下所示
<%= form_for @wine do |f|%>
<p>
<%= f.label :name%>
<%= f.text_field :name%>
</p>
<%= f.fields_for :register do |r|%>
<p>
<%= r.label :simple_name%>
<%= r.text_field :simple_name%>
</p>
<% end %>
<%= f.submit %>
<% end %>
因此,您可以修改wine_params并为您的应用程序细节形成部分