我有一个使用“has_many:through”关系的Rails应用程序。我有3个表/型号。他们是Employee,Store和StoreEmployee。员工可以在一个或多个商店工作。在商店视图(show.html.erb)上,我想要包含一个表单来将员工添加到商店。如果该员工尚不存在,则会将其添加到Employees表中。如果它已经存在,它就会被添加到商店中。
以下是模型定义:
# models
class Employee < ActiveRecord::Base
has_many :store_employees
has_many :stores, :through => :store_employees
attr_accessible :email, :name
end
class Store < ActiveRecord::Base
has_many :store_employees
has_many :employees, :through => :store_employees
attr_accessible :address, :name
end
class StoreEmployee < ActiveRecord::Base
belongs_to :store
belongs_to :employee
attr_accessible :employee_id, :store_id
end
使用rails控制台,我可以证明数据模型正常工作,如下所示:
emp = Employee.first
str = Store.first
str.employees << emp # add the employee to the store
str.employees # shows the employees that work at the store
emp.stores # shows the stores where the employee works
我还更新了我的routes.rb,将employees资源嵌套在store资源下,如下所示:
resources :stores do
resources :employees
end
resources :stores do
resources :employees
end
resources :employees
所以,在商店控制器的show动作中,我认为它应该是这样的:
def show
@store = Store.find(params[:id])
@employee = @store.employees.build # creating an empty Employee for the form
respond_to do |format|
format.html # show.html.erb
format.json { render json: @store }
end
end
这是商店的show.html.erb,包括添加员工的表单:
<p id="notice"><%= notice %></p>
<p>
<b>Name:</b>
<%= @store.name %>
</p>
<p>
<b>Address:</b>
<%= @store.address %>
</p>
<%= form_for([@store, @employee]) do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.submit "Add Employee" %>
<% end %>
<%= link_to 'Edit', edit_store_path(@store) %> |
<%= link_to 'Back', stores_path %>
单击“添加员工”按钮时出现此错误消息:
EmployeesController中的NoMethodError #create
#
的未定义方法`employee_url'
那么,我错过了什么?我认为这与'form_for'有关,但我不确定。我不确定为什么要调用EmployeesController #create。我在使用routes.rb做错了吗?
我不知道添加员工的逻辑应该去哪里。在Employees控制器?存储控制器?
###更新这是EmployeesController中更新的create方法。我收录了米沙回答的建议。
def create
@store = Store.find(params[:store_id])
@employee = @store.employees.build(params[:employee])
respond_to do |format|
if @employee.save
format.html { redirect_to @store, notice: 'Employee was successfully created.' }
format.json { render json: @employee, status: :created, location: @employee }
else
format.html { render action: "new" }
format.json { render json: @employee.errors, status: :unprocessable_entity }
end
end
end
进行此更改后,我成功保存了Employee,但未创建store_employees关联记录。我不知道为什么。这是创建记录时终端中的输出。请注意,商店是SELECTed,而Employee是INSERTed,但这就是全部。没有store_employees记录在任何地方:
Started POST "/stores/1/employees" for 127.0.0.1 at 2012-10-10
13:06:18 -0400 Processing by EmployeesController#create as HTML
Parameters: {"utf8"=>"✓",
"authenticity_token"=>"LZrAXZ+3Qc08hqQT8w0MhLYsNNSG29AkgCCMkEJkOf4=",
"employee"=>{"name"=>"betty", "email"=>"betty@kitchen.com"},
"commit"=>"Add Employee", "store_id"=>"1"} Store Load (0.4ms)
SELECT "stores".* FROM "stores" WHERE "stores"."id" = ? LIMIT 1
[["id", "1"]] (0.1ms) begin transaction SQL (13.9ms) INSERT
INTO "employees" ("created_at", "email", "name", "updated_at") VALUES
(?, ?, ?, ?) [["created_at", Wed, 10 Oct 2012 17:06:18 UTC +00:00],
["email", "betty@kitchen.com"], ["name", "betty"], ["updated_at", Wed,
10 Oct 2012 17:06:18 UTC +00:00]] (1.3ms) commit transaction
Redirected to http://localhost:3000/stores/1 Completed 302 Found in
23ms (ActiveRecord: 15.6ms)
答案 0 :(得分:1)
问题是由EmployeesController#create
方法的代码段引起的:
redirect_to @employee
这会尝试使用employee_url
,但这不存在,因为您已在路径文件中嵌套了employees资源。解决方案是添加“unnested”资源:
resources :stores do
resources :employees
end
resources :employees
或者只是重定向到其他位置。例如。回到StoresController#show
。
顺便说一句,默认的脚手架不会按照您的预期执行:它不会创建与商店相关的员工。为此,你必须稍微改写一下:
def create
@store = Store.find(params[:store_id])
@employee = @store.employees.build(params[:employee])
respond_to do |format|
if @employee.save
format.html { redirect_to @employee, notice: 'Employee was successfully created.' }
format.json { render json: @employee, status: :created, location: @employee }
else
format.html { render action: "new" }
format.json { render json: @employee.errors, status: :unprocessable_entity }
end
end
end