Rails表单 - 选择字段,显示全名但提交ID

时间:2017-05-16 09:06:28

标签: ruby-on-rails forms

我正在尝试通过成员控制器在组和员工之间添加关联。在这种关联的形式中,我希望显示两个字符串属性,但要提交一个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到成员资格#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'=)

我做错了什么?

由于

2 个答案:

答案 0 :(得分:1)

To solve your First error
1. create a full_name method in Employee model it self. like

def full_name
  self.lastname + self.firstname
end

so you can directly access full_name where ever you want

ex:

@employee = Employee.find(params[:employee_id])
@full_name = @employee.full_name
  1. Second error

in your controller

change params[:group_id] and params[:employee_id] to params[:membership][:employee_id] and params[:membership][:group_id].

like

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

答案 1 :(得分:1)

To address the first issue: you are calling the #fullname method on instances of your Employee model, having the method in your controller does nothing, you will need to move it into the model and change it to something like:

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

The second issue is, about the way the parameters are set. The employee_id is sent to the controller as part of the form, if you look at the parameters being sent in your request we can see:

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

so the employee_id is being correctly sent, however because it is part of the form for a membership model, it get sent as part of membership models parameters, in params[:membership][:employee_id], but you are trying to access it with params[:employee_id]

However because you are already sending the group_id and employee_id as parameters to your controller action, you do not need to create an instance of employee and build from it, the id is already being set, so you can change:

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

to:

def create
  Membership.save(membership_params)
  ...
end

private

def membership_params
  params.require(:membership).permit(:group_id, :employee_id)
end