我有两个模型,A Workout
和WorkoutEquipment
。
class Workout < ActiveRecord::Base
belongs_to :exercise
belongs_to :session
belongs_to :workout_equipments
accepts_nested_attributes_for :workout_equipments
end
class WorkoutEquipment < ActiveRecord::Base
has_many :workout
has_many :equipment
end
My / new看起来像这样:
背后的形式看起来像这样:
<%= form_for(@workout) do |f| %>
<% if @workout.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@workout.errors.count, "error") %> prohibited this workout from being saved:</h2>
<ul>
<% @workout.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :exercise_id %><br>
<%= f.select :exercise_id, Exercise.all.collect{|t| [t.name, t.id]}, {prompt: true} %>
</div>
<div class="field">
<%= f.label :session_id %><br>
<%= f.select :session_id, Session.all.collect{|t| [t.when, t.id]}, {prompt: true} %>
</div>
<%= fields_for(:workout_equipment) do |u| %>
<div class="field">
<%= u.label :equipment_id %><br>
<%= u.select :equipment_id, Equipment.all.collect{|t| [t.name, t.id]}, {prompt: true} %>
</div>
<div class="field">
<%= u.label :equipment_weight %><br>
<%= u.number_field :weight %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
但是,当我提交时,尽管accepts_nested_attributes_for :workout_equipments
,workout_equipments.id
并未放入workout
对象。输出日志如下所示:
ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
Processing by WorkoutsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"OSh3xA+usL4/0MAtvRqKio2Vcz/ziLdQ1Rj2vh5zLCXxlVhofoCGh88ssEn+IOc2AXhn3sXWsZn3bIO93hyJMA==", "workout"=>{"exercise_id"=>"4", "session_id"=>"3"}, "workout_equipment"=>{"equipment_id"=>"4", "weight"=>"9001"}, "commit"=>"Create Workout"}
(0.1ms) begin transaction
SQL (0.3ms) INSERT INTO "workout_equipments" ("equipment_id", "weight", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["equipment_id", 4], ["weight", 9001.0], ["created_at", "2016-01-27 02:56:56.611731"], ["updated_at", "2016-01-27 02:56:56.611731"]]
(6.1ms) commit transaction
(0.1ms) begin transaction
SQL (0.3ms) INSERT INTO "workouts" ("exercise_id", "session_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["exercise_id", 4], ["session_id", 3], ["created_at", "2016-01-27 02:56:56.640104"], ["updated_at", "2016-01-27 02:56:56.640104"]]
(7.4ms) commit transaction
(0.0ms) begin transaction
(0.0ms) commit transaction
如您所见,仅记录exercise_id
和session_id
。
我的相关控制器操作如下:
def create
@workout_equipment = WorkoutEquipment.create(workout_equipment_params)
@workout = Workout.create(workout_params)
respond_to do |format|
if @workout.save
format.html { redirect_to @workout, notice: 'Workout was successfully created.' }
format.json { render :show, status: :created, location: @workout }
else
format.html { render :new }
format.json { render json: @workout.errors, status: :unprocessable_entity }
end
end
end
def workout_equipment_params
params.require(:workout_equipment).permit(:workout_id, :equipment_id, :weight)
end
def workout_params
params.require(:workout).permit(:exercise_id, :session_id, :workout_equipments_id)
end
我还需要为params
方法做些什么吗?
答案 0 :(得分:2)
在你的模型中,belongs_to&amp; accepts_nested_attributes_for方法应该采用:workout_equipment
(注意它是单数形式,而不是复数形式)
class Workout < ActiveRecord::Base
belongs_to :exercise
belongs_to :session
belongs_to :workout_equipment
accepts_nested_attributes_for :workout_equipment
end
在您的控制器中,您不需要构建workout_equipment对象,因为nested_attributes
会为您执行此操作:
def create
@workout = Workout.create(workout_params)
respond_to do |format|
if @workout.save
format.html { redirect_to @workout, notice: 'Workout was successfully created.' }
format.json { render :show, status: :created, location: @workout }
else
format.html { render :new }
format.json { render json: @workout.errors, status: :unprocessable_entity }
end
end
end
出于同样的原因,您不需要workout_equipment_params
并且应该丰富您的workout_params
方法:
def workout_params
params.require(:workout).permit(:exercise_id, :session_id, workout_equipment_attributes: [:id, :workout_id, :equipment_id, :weight])
end
我可能误解了您在每个模型中的属性,因此相应地修改了参数。通常,您将nested_attributes发送到workout_equipment_attributes
哈希。
答案 1 :(得分:1)
您需要更改关联名称(当plural
}时,您正在使用singular
):
#app/models/workout.rb
class Workout < ActiveRecord::Base
belongs_to :workout
belongs_to :session
belongs_to :workout_equipment
accepts_nested_attributes_for :workout_equipment
end
#app/models/workout_equipment.rb
class WorkoutEquipment < ActiveRecord::Base
has_many :workouts
end
#app/controllers/workouts_controller.rb
class WorkoutsController < ApplicationController
def new
@equipment = Equipment.all
@workout = Workout.new
@workout.build_workout_exercise
end
def create
@workout = Workout.new workout_params
@workout.save
end
private
def workout_params
params.require(:workout).permit(workout_exercise_attributes: [:equipment_id, :weight])
end
end
#app/views/workouts/new.html.erb
<%= form_for @workout do |f| %>
<%= f.fields_for :workout_exericse do |w| %>
<%= w.collection_select :equipment_id, @equipment, :id, :name %>
<%= w.number_field :weight %>
<% end %>
<%= f.submit %>
<% end %>