Rails:belongs_to 通过未填充的表单进行关联
Rails: belongs_to association through a form not populating
我正在为我的 class、Project
开发控制器。它与 Client
.
有 belongs_to
关系
我不确定为什么会这样,但是当我通过表单创建一个新项目时,它分配了一个 name
,但没有 fee
也没有 client_id
.
相关代码如下:
项目负责人
class ProjectsController < ApplicationController
def index
end
def show
end
def new
@project = Project.new
end
def edit
end
def create
@project = Project.new(project_params)
if @project.save
redirect_to projects_url
else
render 'new'
end
end
def update
end
def destroy
end
private
def project_params
params.require(:project).permit(:name, :feee, :client_id)
end
end
projects/new 查看
<div id="newproject-form">
<h1>Create a project</h1>
<%= form_for @project do |p| %>
<div id="newproject-form-input">
<ul>
<li><%= p.label :name, "Project name: " %><br>
<%= p.text_field :name, size: 40 %></li>
<li><%= p.label :fee, "Fee: " %><br>
<%= p.text_field :fee %></li>
<li><%= p.label :client, "Client name: " %><br>
<%= collection_select(:client_id, :name, current_user.clients, :id, :name) %></li>
<li><%= p.submit "Create project", class: "form-button" %>, or <%= link_to "Cancel",
root_path %></li>
</ul>
</div>
<% end %>
</div>
项目模型
class Project < ActiveRecord::Base
belongs_to :client
end
要使 fee 生效,您需要更正 project_params
中的拼写错误
对于 client_id,试试这个:
里面views/projects/new
<%= collection_select(:project, :client_id, current_user.clients, :id, :name) %>
或
<%= p.collection_select(:client_id, current_user.clients, :id, :name) %>
当你使用 collection_select
时,前两个参数是集合描述的对象和属性(在本例中是你的 project
对象和 client_id
属性)所以当你写 collection_select(:client_id, :name, current_user.clients, :id, :name)
Rails 实际上正在接收一个看起来像 { client_id: {name: 'Something'} }
的对象,您完全忽略了它,而我的代码将 :client_id 添加到项目对象中,这是您的代码所期望的。
使用表单生成器(在本例中是您的 p
对象)可以让您省略 'object' 参数,因为表单生成器已经知道它正在为哪个对象生成表单。
您必须在表单生成器上调用 collection_select
:
# change this
<%= collection_select(:client_id, :name, current_user.clients, :id, :name) %>
# to this
<%= p.collection_select(:client_id, current_user.clients, :id, :name) %>
通过使用 FormBuilder p
,您告诉 collection_select
您正在编辑一个项目对象(参见 p.object
到 return 表单生成器的对象) .
如果您查看 collection_select
文档 (http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/collection_select):
collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
如果您自己调用 collection_select
(而不是从 form_for
方法提供的表单生成器),您必须将对象名称作为第一个参数。在您的情况下,生成 params[:project][:client_id]
.
之类的参数应该是 collection_select(:project, :client_id, #etc.)
我正在为我的 class、Project
开发控制器。它与 Client
.
belongs_to
关系
我不确定为什么会这样,但是当我通过表单创建一个新项目时,它分配了一个 name
,但没有 fee
也没有 client_id
.
相关代码如下:
项目负责人
class ProjectsController < ApplicationController
def index
end
def show
end
def new
@project = Project.new
end
def edit
end
def create
@project = Project.new(project_params)
if @project.save
redirect_to projects_url
else
render 'new'
end
end
def update
end
def destroy
end
private
def project_params
params.require(:project).permit(:name, :feee, :client_id)
end
end
projects/new 查看
<div id="newproject-form">
<h1>Create a project</h1>
<%= form_for @project do |p| %>
<div id="newproject-form-input">
<ul>
<li><%= p.label :name, "Project name: " %><br>
<%= p.text_field :name, size: 40 %></li>
<li><%= p.label :fee, "Fee: " %><br>
<%= p.text_field :fee %></li>
<li><%= p.label :client, "Client name: " %><br>
<%= collection_select(:client_id, :name, current_user.clients, :id, :name) %></li>
<li><%= p.submit "Create project", class: "form-button" %>, or <%= link_to "Cancel",
root_path %></li>
</ul>
</div>
<% end %>
</div>
项目模型
class Project < ActiveRecord::Base
belongs_to :client
end
要使 fee 生效,您需要更正 project_params
对于 client_id,试试这个:
里面views/projects/new
<%= collection_select(:project, :client_id, current_user.clients, :id, :name) %>
或
<%= p.collection_select(:client_id, current_user.clients, :id, :name) %>
当你使用 collection_select
时,前两个参数是集合描述的对象和属性(在本例中是你的 project
对象和 client_id
属性)所以当你写 collection_select(:client_id, :name, current_user.clients, :id, :name)
Rails 实际上正在接收一个看起来像 { client_id: {name: 'Something'} }
的对象,您完全忽略了它,而我的代码将 :client_id 添加到项目对象中,这是您的代码所期望的。
使用表单生成器(在本例中是您的 p
对象)可以让您省略 'object' 参数,因为表单生成器已经知道它正在为哪个对象生成表单。
您必须在表单生成器上调用 collection_select
:
# change this
<%= collection_select(:client_id, :name, current_user.clients, :id, :name) %>
# to this
<%= p.collection_select(:client_id, current_user.clients, :id, :name) %>
通过使用 FormBuilder p
,您告诉 collection_select
您正在编辑一个项目对象(参见 p.object
到 return 表单生成器的对象) .
如果您查看 collection_select
文档 (http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/collection_select):
collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
如果您自己调用 collection_select
(而不是从 form_for
方法提供的表单生成器),您必须将对象名称作为第一个参数。在您的情况下,生成 params[:project][:client_id]
.
collection_select(:project, :client_id, #etc.)