「has_many :through」関係を使用する Rails アプリがあります。私は3つのテーブル/モデルを持っています。それらは、Employee、Store、および StoreEmployee です。従業員は、1 つ以上の店舗で働くことができます。Store ビュー (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 を更新して、従業員リソースを store リソースの下に次のように入れ子にしました。
resources :stores do
resources :employees
end
編集: リソース :employees を「ネストされていない」リソースとして追加しました。そのため、次のようになります。
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#create の NoMethodError
未定義のメソッド「employee_url」 #
それで、私は何が欠けていますか?「form_for」に関係していると思いますが、よくわかりません。EmployeesController#create が呼び出される理由がわかりません。routes.rb に何か問題がありますか?
従業員を追加するためのロジックがどこにあるのかわかりません。従業員コントローラーで?ストアコントローラー?
### アップデート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
この変更を行った後、従業員は正常に保存されましたが、store_employees 関連付けレコードは作成されません。理由がわかりません。レコードを作成するときの端末の出力は次のとおりです。店舗が選択され、従業員が挿入されていることに注意してください。どこにも 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)