Has_many rail model: through associations

I'm trying to customize my relationships, but I'm having problems using associations.

So, I have three Workout models, Exercise and WorkoutExercise . A workout should have a lot of exercises, and the exercise should have different workouts, so I wrote:

 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 

I run some tests, but the tests fail as soon as I create a workout, exercise, and then join them in the workout_exercise class. This will not allow me to access the exercises in the workout as follows:

 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 

My database tables are as follows:

 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 

When I run these tests, he says that the exercises are undefined. Does anyone have any idea?

+7
source share
2 answers

So your WorkoutExercises table cannot be empty. Here's how it should look:

 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 

In addition, you can name this table, whatever you want, it should not be WorkoutExercises. However , if you used the has_and_belongs_to_many relationship, your table would have to be called ExercisesWorkout. Please note that exercises are performed before training. Names should be sorted alphabetically. Do not ask me why this is just a Rails convention.

So, in this case, you can make sure your table is called WorkoutExercises. But if I were you, I would change it to ExercisesWorkout just in case, so you never make a mistake.

+10
source

Your code looks fine. Perhaps the has_and_belongs_to_many error is the best choice. See Choosing between has_many: through and has_and_belongs_to_many

+1
source

All Articles