表格在Rails视图中呈现两次

时间:2015-09-08 05:49:06

标签: ruby-on-rails

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

2 个答案:

答案 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
顺便说一句:不要只是复制这个控制器,我很确定你的整个锻炼/提升逻辑是关闭的。