2012-03-10 4 views
7

나는 관계를 완성하려고 노력하고 있지만 연관성을 사용하는 데 문제가 있습니다.레일 모델 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 개의 테이블을 보여주십시오. 그리고 나는 Yanhao의 제안을 잠시 무시해야한다고 생각합니다. 코드가 올바르므로 지금은 변경하지 않아도됩니다. 너는 다른 것을 놓치고있다. – Ashitaka

+0

@Ashitaka 위의 표를 추가했는데 CreateWorkoutExercises 테이블과 아무 관계가 없습니까? 이것은 처음으로 habtm을 사용하는 것입니다. – trev9065

+0

그래, 그게 다야. 두 테이블 사이의 연결을 설정 한 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이어야합니다. 운동 전에 운동이 어떻게되는지 알아보십시오. 이름은 사전 순으로 정렬해야합니다. 이유를 묻지 마라, 그것은 레일스 대회 일 뿐이다.

그래서이 경우 WorkoutExercises라는 테이블을 사용하면됩니다. 하지만 내가 너라면, 나는 그것을 ExercisesWorkout으로 바꿀 것이다. 그래서 그것을 잘못 이해하지 말라.

+1

감사합니다. @Ashitaka. Rails 4에서 컬럼과 인덱스 이전은 't.references : exercise, index : true' 한 줄로 작성 될 수 있습니다. – scarver2

1

코드가 정상적으로 보입니다. 어쩌면 버그 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

관련 문제