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.)