我正在尝试通过成员控制器在组和员工之间添加关联。在这种关联的形式中,我希望显示两个字符串属性,但要提交一个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.lastname
和employee.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'=)
我做错了什么?
由于
答案 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
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