【问题标题】:Table rendering twice in Rails view在 Rails 视图中表格渲染两次
【发布时间】:2015-09-08 05:49:06
【问题描述】:

Rails 和一般编程的新手,所以这里可能缺少一些基本的东西。我正在制作一个带有 3 个模型的简单运动追踪器:运动(不同类型的运动表)、锻炼(该会话完成的运动表)、提升(两者之间的连接表,还包括重量、组数和次数每个练习完成)。

问题:在锻炼中添加超过 1 个练习后,显示视图上的表格会为每个练习呈现超过 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

还有 Lifts 模型

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

【问题讨论】:

  • 请告诉我们您的app/models/workout.rb
  • 刚刚添加到上面。谢谢
  • 你能解释一下LiftExercise模型之间的关系吗?
  • 锻炼和锻炼模型通过升降机有很多关系。锻炼模型列出了不同类型的锻炼(卧推、肩推等),Lift 模型还包括在特定锻炼期间完成了每个锻炼的多少(例如,2 组、10 公斤、5 次重复)。跨度>
  • 如果我理解正确,这应该可以。如果不是,请给我错误,并附加另外两个模型的代码来提问。

标签: ruby-on-rails


【解决方案1】:

您的练习是两次,因为您对 @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>

【讨论】:

  • Asiniy - 您是否在修改后的代码中缺少右括号?想不通
  • @workout.exercises.inlcludes(:lifts).each 做 |exercise|
  • 谢谢大家-这正在工作。将再次考虑模型之间的逻辑,因为某些东西似乎有点偏离或至少不理想
  • 如果我理解正确的话,这段代码只会显示第一次升降机,在特定锻炼的锻炼中可以有多次升降机。
  • @BooVeMan 锻炼只有一次与锻炼相关的提升。
【解决方案2】:

是的,你是新人,看到你的控制器后,我不再阅读你的问题,所以我会给你一些帮助,帮助你编写更好的控制器。

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

不要创建一个 new 对象然后保存它 - 而是直接调用 create 方法。 虽然锻炼有很多电梯,但电梯会自动建立正确的关联,因此无需手动设置。

对不起劫持,只是想让你知道如何编写更好的控制器:-)

编辑

或者干脆干了

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

edit2:或者完全做空

如果内部没有任何反应,则无需写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

顺便说一句:不要只是复制这个控制器,我很确定你的整个锻炼/升降逻辑是关闭的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-19
    • 1970-01-01
    • 2018-10-27
    • 2023-04-09
    • 1970-01-01
    • 2015-03-01
    相关资源
    最近更新 更多