2012-03-10 20 views
7

Estoy tratando de que mis relaciones funcionen pero tengo problemas para usar las asociaciones.rails model has_many: a través de asociaciones

Tengo tres modelos Workout, Exercise y WorkoutExercise. Una sesión de ejercicios debe tener muchos ejercicios y un ejercicio debería tener diferentes entrenamientos, por tanto, escribí:

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 

Me postulo algunas pruebas, pero las pruebas no están pasando una vez que se crea un entrenamiento, ejercicio y luego uno a ellos en el workout_exercise clase. No me deja acceder a los ejercicios en el entrenamiento de esta manera:

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 

Mis tablas de la base se ven así:

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 

Cuando corro esta prueba se dice exercises no está definido. ¿Alguien tiene alguna idea?

+0

¿Has ejecutado tus migraciones? Por favor muéstranos tus 3 tablas. Y creo que deberías ignorar la sugerencia de Yanhao por un tiempo. Tu código parece ser correcto, así que no tienes que cambiarlo por ahora. Te estás perdiendo algo más. – Ashitaka

+0

@Ashitaka Agregué las tablas de arriba, ¿tendría algo que ver con que la tabla CreateWorkoutExercises está vacía? Esta es la primera vez que uso habtm. – trev9065

+0

Ok, eso fue todo. Echas de menos los identificadores que establecieron la conexión entre las dos tablas. Probablemente quiera volver a crear sus migraciones ahora. Creo que 'rake db: reset' hará el trabajo (aunque borrará todos tus registros). – Ashitaka

Respuesta

10

Ok, entonces su tabla de EjerciciosEjercicios no puede estar vacía. Esta es la forma en que debe ser:

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 

Además, puede nombrar a esta mesa lo desea, no tiene por qué ser WorkoutExercises. Sin embargo,, si usaba una relación has_and_belongs_to_many, su tabla tendría que obligatoriamente llamarse ExercisesWorkout. Observe cómo los Ejercicios vienen antes del Entrenamiento. Los nombres deben ordenarse alfabéticamente. No me preguntes por qué, es solo una convención de Rails.

Por lo tanto, en este caso, le irá bien con su tabla que se llama WorkoutExercises. Pero si fuera tú, lo cambiaría a ExercisesWorkout, por si acaso, para que nunca te equivocas.

+1

Gracias @Ashitaka. En Rails 4, la migración de columna e índice se puede escribir en una línea 't.references: exercise, index: true' – scarver2

Cuestiones relacionadas