导轨模型has_many:通过关联

问题描述:

我想让我的关系解决,但我在使用关联时遇到了问题。导轨模型has_many:通过关联

所以我有三个型号Workout,ExerciseWorkoutExercise。锻炼应该有很多练习和锻炼应该有不同的训练,因此我写了:

class Workout < ActiveRecord::Base 
    has_many :workout_exercises 
    has_many :exercises, :through => :workout_exercises 
end 

class Exercise < ActiveRecord::Base 
    has_many :workout_exercises 
    has_many :workouts, :through => :workout_exercises 
end 

class WorkoutExercise < ActiveRecord::Base 
    belongs_to :exercise 
    belongs_to :workout 
end 

我运行一些测试,但测试没有通过一次我创建了一个锻炼,运动,然后在workout_exercise加入他们的行列类。它不会让我访问的练习在这样的锻炼:

Workout.create 
Exercise.create 
WorkoutExercise.create(:workout => Workout.first, :exercise => Exercise.first) 
work = Workout.first 
work.exercises.count #This line causes the error: undefined method exercises 

我的数据库表如下所示:

class CreateWorkouts < ActiveRecord::Migration 
    def change 
    create_table :workouts do |t| 
     t.string :title 
     t.text :description 
     t.float :score 
     t.timestamps 
    end 
    end 
end 

class CreateExercises < ActiveRecord::Migration 
    def change 
    create_table :exercises do |t| 
     t.string :title 
     t.text :description 
     t.float :value 
     t.timestamps 
    end 
    end 
end 

class CreateWorkoutExercises < ActiveRecord::Migration 
    def change 
    create_table :workout_exercises do |t| 
     t.timestamps 
    end 
    end 
end 

当我运行这个测试中,它说exercises是不确定的。有没有人有任何想法?

+0

你有没有运行你的迁移?请向我们展示您的3张桌子。我认为你应该暂时忽略艳豪的建议。你的代码似乎是正确的,所以你现在不必改变它。你错过了别的东西。 – Ashitaka 2012-03-10 02:44:49

+0

@Ashitaka我添加了上面的表格,它与CreateWorkoutExercises表是空的有关吗?这是我第一次使用habtm。 – trev9065 2012-03-10 03:15:01

+0

好吧,就这样。您错过了建立两个表格之间连接的ID。您可能现在想要重新创建您的迁移。我认为'rake db:reset'会完成这项工作(它会删除你所有的记录)。 – Ashitaka 2012-03-10 03:32:21

好吧,您的WorkoutExercises表不能为空。这是它应该看起来如何:

class CreateWorkoutExercises < ActiveRecord::Migration 
    def change 
    create_table :WorkoutExercises do |t| 
     t.integer :exercise_id, :null => false 
     t.integer :workout_id, :null => false 

     t.timestamps 
    end 

    # I only added theses indexes so theoretically your database queries are faster. 
    # If you don't plan on having many records, you can leave these 2 lines out. 
    add_index :WorkoutExercises, :exercise_id 
    add_index :WorkoutExercises, :workout_id 
    end 
end 

此外,您可以任意命名此表,它不必是WorkoutExercises。 但是,如果您使用的是has_and_belongs_to_many关系,则您的表格必须强制命名为ExercisesWorkout。注意锻炼之前锻炼是如何发生的。名称必须按字母顺序排列。不要问我为什么,这只是一个Rails约定。

因此,在这种情况下,您可以在您的表名为WorkoutExercises的情况下做得很好。但如果我是你,我会将它改为ExercisesWorkout,以防万一,以免你错。

+1

谢谢@Ashitaka。在Rails 4中,列和索引迁移可以写成一行't.references:exercise,index:true' – scarver2 2014-08-20 12:28:16

您的代码看起来不错。错误也许has_and_belongs_to_many是一个更好的选择。请参阅Choosing Between has_many :through and has_and_belongs_to_many

+0

我相信has_and_belongs_to_many关联已被弃用。 http://stackoverflow.com/questions/7850111/rails-3-1-has-and-belongs-to-many-deprecated – Ben 2013-07-23 11:30:59