Just before I answer, I'm going to indicate that the typical Ruby convention (which is important for the DataMapper, which you will see per second) should have class names like SelectedWorkout and WorkoutItem, not Selectedworkout and Workoutitems. DataMapper automatically determines your relationships from class names, so itβs useful to follow the convention. Sorry if this is confusing, but for the purpose of the answer, I'm going to suggest that you can rename your models:
Given that your training model is essentially a normalized dataset from WorkoutItem, I would suggest that WorkoutItem.belongs_to(:workout) (and, by the way, a command that you could run from IRB, and it would work fine , or you can stick belongs_to :workout in the model class, of course).
It seems that SelectedWorkout is your main interface in your data, so I assume that you will do things like saying @user.selected_workouts.first.workout_items (for the first selected workout items) or the like.
By the way, you can go further and use WorkoutItem as a model for the connection between Workout and SelectedWorkout if the following relationships are established:
WorkoutItem.belongs_to(:workout)
WorkoutItem.belongs_to(:selected_workout)
SelectedWorkout.has(Infinity, :workout_items) # n == Infinity inside a Model
Once the previous relationship is set up, you can say:
SelectedWorkout.has(Infinity, :workouts, :through => :workout_items)
Similarly, you have created another side that has many relationships:
Workout.has(Infinity, :workout_items)
Workout.has(Infinity, :selected_workouts, :through => :workout_items
Now you can do cool things like @selected_workout.workouts.map{ |w| w.name } @selected_workout.workouts.map{ |w| w.name } . Or, if you want to find all the selected workouts that include a specific workout, you can say @workout.selected_workouts .
Or you can do more interesting things using the DataMapper query syntax as follows:
@workouts_that_dont_require_gear = SelectedWorkouts.all("workouts.name" => ["Situps", "Pullups", "Pushups"])