【问题标题】:Rails form - select field, display fullname but submit IDRails 表单 - 选择字段,显示全名但提交 ID
【发布时间】:2017-05-16 09:06:27
【问题描述】:

我正在尝试通过成员控制器在组和员工之间添加关联。在此关联的表单中,我希望显示两个字符串属性,但要提交一个 ID。

我的会员控制器需要一个 group_id 和一个 employee_id 来执行创建操作:

def create
    @employee = Employee.find(params[:employee_id])
    @membership = @employee.memberships.build(group_id: params[:group_id])
    if @membership.save
      flash[:notice] = "Collaborateur ajouté au groupe."
      redirect_to groups_url
    else
      flash[:error] = "Erreur lors de l'ajout du collaborateur."
      redirect_to groups_url
    end
  end

groups/show.html.erb 页面我有一个link_to 到membership#new 操作,它将group_id 作为参数传递并呈现新的会员表格。在该表单中,我有一个选择字段,我想在其中显示 employee.lastnameemployee.firstname,但提交所选员工的 id 而不是显示的值。

表格

<%= form_for(@membership, :html => {class: 'form-horizontal'}) do |f| %>

    <div class="box-body">
      <%= f.hidden_field :group_id, value: params[:group_id] %>
      <div class="form-group">
        <%= f.label :employee_id, class: 'col-sm-3 control-label' %>
        <div class="col-sm-9">
          <%= f.select(:employee_id, Employee.all.map{|e| [e.fullname, e.id]},
          {prompt: 'Selectionner'}, { class: 'form-control' } ) %>
        </div>
      </div>

    </div>
    <div class="box-footer">
      <%= f.submit "Valider", class: "btn btn-primary pull-right" %>
    </div>

我对该表格有 2 个问题:

首先,fullname 方法不起作用,导致表单无法显示和服务器打印:

ActionView::Template::Error (undefined method `fullname' for
 #<Employee:0x007fc458e61738>)

fullname 方法在EmployeesController 中定义

def fullname
    @employee = Employee.find(params[:id])
    fullname = "#{@employee.firstname} #{@employee.lastname}"
  end

其次,我尝试了相同的语法并将fullname 方法替换为lastname 属性,然后显示表单,但是在提交未找到记录时出现错误:

Started POST "/memberships" for ::1 at 2017-05-16 10:55:52 +0200
Processing by MembershipsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"1gJ5VQjNemlEC/8H2O1eutJtyHPArqDMrT8RXZ9rNMp2PUu/ux1SzIgbzCFsL3Jc4mOJ+aZvX7RSwVUIJoruow==", "membership"=>{"group_id"=>"1", "employee_id"=>"4"}, "commit"=>"Valider"}
  Employee Load (0.4ms)  SELECT  "employees".* FROM "employees" WHERE "employees"."id" = ? LIMIT ?  [["id", nil], ["LIMIT", 1]]
Completed 404 Not Found in 6ms (ActiveRecord: 0.4ms)



ActiveRecord::RecordNotFound (Couldn't find Employee with 'id'=)

我做错了什么?

谢谢

【问题讨论】:

    标签: ruby-on-rails forms


    【解决方案1】:

    解决您的第一个错误
    1.在Employee模型中创建一个full_name方法。喜欢

    def full_name
      self.lastname + self.firstname
    end
    

    这样您就可以在任何地方直接访问full_name

    例如:

    @employee = Employee.find(params[:employee_id])
    @full_name = @employee.full_name
    
    1. 第二个错误

    在你的控制器中

    params[:group_id]params[:employee_id] 更改为params[:membership][:employee_id]params[:membership][:group_id]

    喜欢

    def create
        @employee = Employee.find(params[:membership][:employee_id])
        @membership = @employee.memberships.build(group_id: params[:membership][:group_id])
        if @membership.save
          flash[:notice] = "Collaborateur ajouté au groupe."
          redirect_to groups_url
        else
          flash[:error] = "Erreur lors de l'ajout du collaborateur."
          redirect_to groups_url
        end
      end
    

    【讨论】:

    • 欢迎 :) @Arnaud
    【解决方案2】:

    要解决第一个问题:您在 Employee model 的实例上调用 #fullname 方法,而控制器中的方法没有任何作用,您需要将其移动到模型中并将其更改为:

    def fullname
      "#{firstname} #{lastname}"
    end
    

    第二个问题,关于参数设置的方式。 employee_id 作为表单的一部分发送到控制器,如果您查看请求中发送的参数,我们可以看到:

    "membership"=>{"group_id"=>"1", "employee_id"=>"4"}
    

    因此employee_id 被正确发送,但是因为它是成员模型表单的一部分,它作为成员模型参数的一部分在params[:membership][:employee_id] 中发送,但您正尝试使用params[:employee_id] 访问它

    但是,由于您已经将 group_id 和 employee_id 作为参数发送到控制器操作,因此您无需创建员工实例并从中构建,id 已经设置好,因此您可以更改:

    def create
      @employee = Employee.find(params[:employee_id])
      @membership = @employee.memberships.build(group_id: params[:group_id])
      ....
    end
    

    到:

    def create
      Membership.save(membership_params)
      ...
    end
    
    private
    
    def membership_params
      params.require(:membership).permit(:group_id, :employee_id)
    end
    

    【讨论】:

    • @Arnaud 我已在我的答案中进一步添加,以帮助您简化您在控制器中所做的事情,我希望它可以提供帮助。
    • 感谢您的回答,我已尝试按照您的方式进行操作,但我仍然收到相同的错误 RecordNotFound for employee 'id=' ... 上面 Narasimha Reddy 的答案通过访问 params [ :membership][:employee_id] 而不仅仅是 params[:employee_id]
    • @Arnaud 是的,但是在 Rails 中,为此目的使用表单参数是不好的做法,表单参数是设置模型的属性,你应该使用 StrongParameters 来做到这一点,比如在我上面展示的membership_params 方法中,您不需要创建@employee 实例变量来保存您的会员记录,这是一个无用的命令,并且会无缘无故地增加您的SQL命中。请参阅此处了解如何使用 StrongParameters:edgeapi.rubyonrails.org/classes/ActionController/…
    • 我知道使用字符串参数是一种很好的做法,所以不要这样做是不好的......为了构建我当前的应用程序,我遵循了 Michael Hartl 的 Rails 教程并使用构建一些模型 + 表单强参数。在这种连接模型的情况下,我只是无法使其正常工作。我需要更多的练习来理解通过模型和控制器调用事物的方式,并理解变量范围。我将尝试重构我的代码以适应强参数的使用,如果您知道在 Rails 中处理变量范围/调用的良好资源,请告诉我:)
    猜你喜欢
    • 1970-01-01
    • 2019-05-21
    • 2019-09-21
    • 2015-11-04
    • 1970-01-01
    • 1970-01-01
    • 2012-05-05
    • 2019-11-21
    • 1970-01-01
    相关资源
    最近更新 更多