Rails ActiveRecord belongs_to关联未加载

时间:2016-02-24 20:53:32

标签: ruby-on-rails ruby activerecord

我正在尝试按如下方式呈现Active Records列表:

<% @workout_sets.each do |workout_set| %>
  <tr>
    <td><%= workout_set.reps %></td>
    <td><%= workout_set.exercise.name %></td>
    <td><%= link_to 'Show', workout_set %></td>
    <td><%= link_to 'Edit', edit_workout_set_path(workout_set) %></td>
    <td><%= link_to 'Destroy', workout_set, method: :delete, data: { confirm: 'Are you sure?' } %></td>
  </tr>
<% end %>

我的AR设置如下:

class WorkoutSet < ActiveRecord::Base
  belongs_to :workout
  belongs_to :exercise, class_name: 'Exercise', foreign_key: 'exercises_id'
end

class Exercise < ActiveRecord::Base
end

class Workout < ActiveRecord::Base
  has_many :workout_set
end

我的架构是

create_table "exercises", force: :cascade do |t|
  t.string   "name",       null: false
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

add_index "exercises", ["name"], name: "index_exercises_on_name", unique: true

create_table "workout_sets", force: :cascade do |t|
  t.integer  "reps",         null: false
  t.datetime "created_at",   null: false
  t.datetime "updated_at",   null: false
  t.integer  "exercises_id"
 t.integer  "workouts_id"
end

add_index "workout_sets", ["exercises_id"], name: "index_workout_sets_on_exercises_id"
add_index "workout_sets", ["workouts_id"], name: "index_workout_sets_on_workouts_id"

create_table "workouts", force: :cascade do |t|
  t.string   "location",   null: false
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

在尝试渲染页面时,我收到以下错误

  

nil的未定义方法`name':NilClass

当我将模板中的路径更改为<%= workout_set.exercise %>时,它会像444 #<Exercise:0x007fbde9dde998> Show Edit Destroy那样呈现每行,这正是我所期望的。

为什么尝试访问name属性会导致此错误?

2 个答案:

答案 0 :(得分:2)

您的WorkoutSet之一没有关联的Exercise。您可以强制WorkoutSetExercise模型中执行WorkoutSet,但这会产生影响。主要是,如果没有先创建WorkoutSet,则无法创建Exercise。如果这是你想要的,那么将以下内容添加到WorkoutSet模型。

validates_presence_of :exercise_id

更有可能的是,您只想在没有关联Exercise时处理页面崩溃。

<td><%= workout_set.exercise.name unless workout_set.exercise.blank?  %></td>

这会给你一个空白单元格,但你可以做这样的事情来占位符。

<td><%= workout_set.exercise.blank? ? "No exercise for this set" : workout_set.exercise.name %></td>

答案 1 :(得分:0)

您尚未在练习模型

中设置关系
class Exercise < ActiveRecord::Base
  has_many :workout_sets
  has_many :workouts, through: :workouts_sets #not needed but good to setup
end

或者您是否尝试在锻炼与锻炼之间建立一对一的关系

class Exercise < ActiveRecord::Base
  has_one :workout_set
end

还有一个&#39;在workout_sets表中的外键末尾(即&#39; workouts_id&#39;)有些不好。我非常确定Rails会足够聪明以使其正常工作但如果你遇到更多错误我会尝试将这些错误更改为&#39; workout_id&#39;和&#39; exercise_id&#39;。