在我回答之前,我要指出,典型的 ruby 约定(与您稍后将看到的 DataMapper 相关)是具有像 SelectedWorkout 和 WorkoutItem 这样的类名称,而不是 Selectedworkout 和 Workoutitems。 DataMapper 会根据类名自动命名您的关系,因此遵循约定很有用。如果令人困惑,我们深表歉意,但出于答案的目的,我假设您可以重命名模型:
鉴于您的 Workout 模型本质上是 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"])