我有以下用户控制器:
class UsersController < ApplicationController
def index
@users = User.all
end
def new
@user = User.new
end
def create
@user = User.new(user_params)
@customer = Customer.new
if @user.save
flash.notice = "User '#{@user.email}' was succefully created."
redirect_to user_path(@user)
else
render 'new'
end
end
def show
@user = User.find(params[:id])
end
private
def user_params
params.require(:user).permit(:email, :password, :password_confirmation, customer_attributes: [:id, :company])
end
end
我有以下用户模型:
class User < ActiveRecord::Base
has_one :customer
accepts_nested_attributes_for :customer, :allow_destroy => true
end
以下客户模型:
class Customer < ActiveRecord::Base
belongs_to :user
end
最后,这是表格:
<%= form_for [@user] do |f| %>
<% if @user.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@user.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% @user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :email %><br>
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :password %><br>
<%= f.password_field :password %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br>
<%= f.password_field :password_confirmation %>
</div>
<%= f.fields_for :customers do |company| %>
<div class="field">
<%= company.label :company %><br>
<%= company.text_field :company %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
当我提交表单时,我看到:`未经许可的参数:客户&#39;在日志中,但似乎我确实允许它。
另外,我想在show和index视图中显示每个用户的公司名称。我不知道该怎么做。
我记得过去使用build
方法获得类似工作的东西,但这次我似乎无法弄明白。
答案 0 :(得分:6)
继@Mandeep
的答案之后,让我再向您提供一些信息:
- 你需要&#34;建立&#34;您的表单的关联对象
- 您需要根据模型
的关联进行处理- 您需要按照所述关联保存属性
醇>
这样做的方法相对简单(Mandeep
概述)。但是,为什么的原因可能不太明显:
<强>构建强>
首先,您需要建立关联关联。这非常重要,主要是因为Rails(由于构建在Ruby上)是一个object orientated框架。
面向对象,没有太多细节,意味着你使用Rails做的所有将基于对象。对于我们心爱的Rails,这意味着每个Model
都是object
。
凭借这一事实,只要您想创建这样的表单,嵌套模型范例就必须在Rails中构建。要执行此操作,您需要使用build
methods - 告诉ActiveRecord(Rails&#39; object relational mapper)您还有另一个要填充的关联模型/对象:
#app/controllers/users_controller.rb
class UsersController < ApplicationController
def new
@user = User.new #-> initializes "User" object
@user.build_customer #-> "builds" the associated object
end
end
这为Rails提供了一组可以填充表单的相关数据(考虑到你调用了正确的方法)
-
<强>协会强>
其次,您需要考虑您拥有的关联。这很重要,因为奇异和多个关联在&#34; build&#34;中的处理方式不同处理。
您正在使用has_one
关系,这意味着您需要使用单数关联名称(尽管您可以随意调用关联):
如果您使用has_many
关联,则需要使用复数关联方法:
这解释了使用build_customer
方法的必要性;但也应该让你使用单数关联名称来使用所需的所有方法,即fields_for
和params
:
#app/views/users/new.html.erb
<%= form_for @user do |f| %>
...
<%= f.fields_for :customer do |c| %>
...
<% end %>
<%= f.submit %>
<% end %>
#app/controllers/users_controller.rb
class UsersController < ApplicationController
def create
@user = User.new user_params
@user.save
end
private
def user_params
params.permit(:user).permit(:user, :params, customer_attributes: [:x. :y])
end
end
-
保存强>
上述控制器代码将保存您需要的属性。
您必须了解传递嵌套属性意味着您要发送关联数据的模型需要从属于您的&#34; main&#34;模型。如最初所讨论的,模型中的ActiveRecord associations
会发生这种情况。
希望这能让你更清晰
答案 1 :(得分:4)
将您的代码更改为:
def new
@user = User.new
@user.build_customer
end
你的表格:
<%= form_for @user do |f| %>
// user fields
<%= f.fields_for :customer do |customer| %>
// customer fields
<% end %>
<% end %>
此外,您的创建方法中不需要@customer = Customer.new。