Начиная с Datamapper, вопрос об ассоциации - PullRequest
4 голосов
/ 13 мая 2010

Я просто погружаюсь в Datamapper (и Sinatra) и у меня есть вопрос об ассоциациях. Ниже приведены некоторые модели, которые у меня есть. Это то, что я хочу реализовать. У меня проблема с Workoutitems и Workout. Тренировка будет управляться отдельно, но Workoutitems имеет отдельную тренировку, связанную с каждой строкой.

  1. Тренировка - просто список типов тренировки (бег, подъем, нахождение и т. д.)
  2. Выбранные тренировки - это это название набора тренировок, вместе с примечаниями пользователя и тренер. Имеет коллекцию N тренировки
  3. Workoutitems - это требует тренировки и нескольких повторений, которые идут в наборе тренировки.

    class Workout
      include DataMapper::Resource
      property :id,     Serial  #PK id
      property :name,   String, :length=>50,:required=>true  # workout name
      property :description, String, :length=>255  #workout description
    end
    
    
    class Selectedworkout
      include DataMapper::Resource
      property :id,  Serial
      property :name, String, :length=>50, :required=>true
      property :workout_time, String, :length=>20
      property :user_notes, String, :length=>255
      property :coach_notes, String, :length=>255
      has n, :workoutitems
    end
    
    class Workoutitem
      include DataMapper::Resource
      property :id, Serial
      property :reps, String, :length=>50, :required=>true
      belongs_to :selectedworkout
    end
    

1 Ответ

4 голосов
/ 13 мая 2010

Непосредственно перед тем, как я отвечу, я хочу указать, что типичное соглашение ruby ​​(которое актуально для DataMapper, которое вы увидите через секунду) - это иметь имена классов, такие как SelectedWorkout и WorkoutItem, а не Selectedworkout и Workoutitems.DataMapper автоматически называет ваши отношения по именам классов, поэтому полезно следовать соглашению.Извиняюсь, если это сбивает с толку, но с целью ответа, я собираюсь предположить, что вы можете переименовать ваши модели:

Учитывая, что ваша модель тренировки является по сути нормализованным сбором данных из WorkoutItem, я быпредположим, что WorkoutItem.belongs_to(:workout) (и, кстати, это команда, которую вы можете запустить из IRB, и она будет работать просто отлично, или вы можете вставить belongs_to :workout в класс модели, конечно).

Кажется, чтоSelectedWorkout является вашим основным интерфейсом в ваших данных, поэтому я предполагаю, что вы будете делать такие вещи, как: @user.selected_workouts.first.workout_items (для элементов первой выбранной тренировки) или тому подобное.

Кстати, вы можете пойти дальше и использовать WorkoutItemв качестве модели соединения между Workout и SelectedWorkout, если установлены следующие отношения:

WorkoutItem.belongs_to(:workout)

WorkoutItem.belongs_to(:selected_workout)

SelectedWorkout.has(Infinity, :workout_items) # n == Infinity inside a Model

Как только предыдущее отношение установлено, вы можете сказать:

SelectedWorkout.has(Infinity, :workouts, :through => :workout_items)

Аналогично вы настраиваете другую сторону, у которой есть много сквозных отношений аналогично:

Workout.has(Infinity, :workout_items)

Workout.has(Infinity, :selected_workouts, :through => :workout_items

Теперь вы можете делать классные вещи, как @selected_workout.workouts.map{ |w| w.name }.Или, если вы хотите найти все выбранные тренировки, которые включают в себя определенную тренировку, вы можете сказать @workout.selected_workouts.

, или вы можете делать более интересные вещи с помощью синтаксиса запроса DataMapper, например:

@workouts_that_dont_require_gear = SelectedWorkouts.all("workouts.name" => ["Situps", "Pullups", "Pushups"])

...