Модель рельсов has_many: через ассоциации - PullRequest
7 голосов
/ 10 марта 2012

Я пытаюсь наладить свои отношения, но у меня возникают проблемы с использованием ассоциаций.

Итак, у меня есть три модели Workout, Exercise и WorkoutExercise. В тренировке должно быть много упражнений, а в упражнении должны быть разные тренировки, поэтому я написал:

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 не определено. У кого-нибудь есть какие-либо идеи?

Ответы [ 2 ]

11 голосов
/ 10 марта 2012

Хорошо, значит, ваша таблица 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 голос
/ 10 марта 2012

Ваш код выглядит нормально.Возможно, ошибка has_and_belongs_to_many - лучший выбор.См. Выбор между has_many: through и has_and_belongs_to_many

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...