Rails和编程的新手,所以我可能会遗漏一些基本的东西。我正在制作一个简单的运动追踪器,有3个模型:运动(不同类型的运动表),锻炼(该运动完成的运动表),升力(两者之间的联合表,还包括重量,组和代表每项运动完成)。
问题:在锻炼中添加多于1个锻炼后,显示视图上的表格为每个锻炼渲染了多个条目(屏幕截图:http://imgur.com/MMYEkNr)。一切都正确写入数据库。
问题:如何以正确的方式进行渲染以及我做错了什么?
以下是锻炼控制器:
class WorkoutsController < ApplicationController
def index
@workouts = Workout.all
end
def new
@workout = Workout.new
@lift = Lift.new
end
def create
@workout = Workout.new(params[:workout])
@workout.save
@lift = Lift.new(params[:lift])
@lift.workout_id = @workout.id
@lift.save
redirect_to @workout
end
def show
@workout = Workout.find(params[:id])
end
def edit
@workout = Workout.find(params[:id])
end
def update
@workout = Workout.find(params[:id])
@lift = Lift.new(params[:lift])
@lift.workout_id = @workout.id
@lift.save
redirect_to @workout
end
end
这是显示视图
<h1> Workout Number <%= @workout.id %></h1>
<div class="container">
<table class="table table-striped">
<thead>
<th>Excercize</th>
<th>Sets</th>
<th>Reps</th>
<th>Weight</th>
</thead>
<tbody>
<% @workout.exercises.each do |w| %>
<% @workout.lifts.each do |e| %>
<tr>
<td><%= w.name %></td>
<td><%= e.sets %></td>
<td><%= e.reps %></td>
<td><%= e.weight %></td>
</tr>
</tbody>
<% end %>
<% end %>
</table>
</div>
<div class="btn btn-primary">
Add Exercise
<%= link_to 'Add Exercise', edit_workout_path %>
</div>
修改添加锻炼模型:
class Workout < ActiveRecord::Base
attr_accessible :id, :title, :body
has_many :lifts
accepts_nested_attributes_for :lifts
has_many :exercises, through: :lifts
end
提升模型
class Lift < ActiveRecord::Base
attr_accessible :reps, :sets, :weight, :id,
:workout_id, :exercise_id, :exercise_name
belongs_to :exercise
belongs_to :workout
end
练习模型
class Exercise < ActiveRecord::Base
attr_accessible :name, :primary_area, :secondary_area,
:id
has_many :lifts
accepts_nested_attributes_for :lifts
has_many :workouts, through: :lifts
def name_for_select
name.capitalize
end
end
答案 0 :(得分:2)
您的练习是两次,因为您对@workout
模型进行了两次迭代:
<% @workout.exercises.each do |w| %>
<% @workout.lifts.each do |e| %>
<tr>
<td><%= w.name %></td>
<td><%= e.sets %></td>
<td><%= e.reps %></td>
<td><%= e.weight %></td>
</tr>
</tbody> <!-- remove this tag out of the scope -->
<% end %>
<% end %>
要完成所有工作,你需要这样的东西:
<% @workout.exercises.inlcludes(:lifts).each do |exercise| %>
<tr>
<td><%= exercise.name %></td>
<td><%= exercise.lifts.first.sets %></td>
<td><%= exercise.lifts.first.reps %></td>
<td><%= exercise.lifts.first.weight %></td>
</tr>
<% end %>
</tbody>
答案 1 :(得分:1)
是的,你的新人,在看到你的控制器后我停止阅读你的问题了,所以生病给你一些帮助,写下更好的控制器。
def create
workout = Workout.create params[:workout]
workout.lifts.create params[:lift]
redirect_to workout
end
def update
workout = Workout.find(params[:id])
workout.lifts.create params[:lift]
redirect_to workout
end
不要创建新对象,然后保存 - 而只是直接调用create
方法。
虽然锻炼有很多升降机,但电梯会自动正确关联,因此无需手动设置。
抱歉劫持,只是想让你知道如何编写更好的控制器: - )
修改强>
或者只是去DRY
class WorkoutsController < ApplicationController
def index
@workouts = Workout.all
end
def new
@workout = Workout.new
@lift = Lift.new
end
def create
workout = Workout.create params[:workout]
workout.lifts.create params[:lift]
redirect_to workout
end
def show
@workout = current_workout
end
def edit
@workout = current_workout
end
def update
current_workout.lifts.create params[:lift]
redirect_to current_workout
end
private
def current_workout
Workout.find params[:id]
end
end
编辑2:或完全缩短
如果内部没有任何反应,则无需编写def show
。 before_filter正在加载@workout并且将呈现模板。导轨很酷!
class WorkoutsController < ApplicationController
before_filter :load_workout, only: [:show, :edit, :update]
def index
@workouts = Workout.all
end
def new
@workout = Workout.new
@lift = Lift.new
end
def create
workout = Workout.create params[:workout]
workout.lifts.create params[:lift]
redirect_to workout
end
def update
@workout.lifts.create params[:lift]
redirect_to @workout
end
private
def load_workout
@workout = Workout.find params[:id]
end
end
顺便说一句:不要只是复制这个控制器,我很确定你的整个锻炼/提升逻辑是关闭的。