2012-03-10 3 views
7

私は私の関係を整理しようとしていますが、私はアソシエーションを使用する際に問題があります。レールモデルhas_many:スルーアソシエーション

私はWorkoutExerciseWorkoutExerciseという3つのモデルがあります。ワークアウトには多くの練習を持っている必要があり、運動は、したがって、私が書いた別のワークアウトを持っている必要があります。

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 

私のデータベーステーブルは、次のようになります。:私はそれが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 

それは私がこのようなトレーニングの演習にアクセスできなくなります。誰にもアイデアはありますか?

+0

移行を実行しましたか?あなたの3つのテーブルを見せてください。そして、あなたはYanhaoの提案をしばらく無視するべきだと思います。あなたのコードは正しいと思われるので、今のところ変更する必要はありません。あなたは何か他のものを欠いている。 – Ashitaka

+0

@Ashitaka上記の表を追加しましたが、CreateWorkoutExercisesテーブルと何か関係がありますか?これはhabtmを使って初めてのことです。 – trev9065

+0

さて、そうだった。あなたは2つのテーブル間の接続を確立したIDを紛失していました。おそらく、移行を再作成したいと思うでしょう。私は 'rake db:reset'が仕事をしてくれると思っています(あなたのレコードはすべて削除されます)。 – Ashitaka

答えて

10

Okを参照してください。したがって、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にする必要があります。 ExercisesがWorkoutの前にどのように来るかを確認してください。名前はアルファベット順に並べる必要があります。なぜ私に聞かないでください、それは単なるRailsのコンベンションです。

この場合、WorkoutExercisesという名前のテーブルでうまくいくでしょう。しかし、もし私があなただったら、私はそれをExercisesWorkoutに変更したいと思います。

+1

ありがとうございます@俊孝。 Rails 4では、列とインデックスの移行は 't.references:exercise、index:true'という1行で記述できます – scarver2

関連する問題