Starting with Datamapper, Association Question

I just dive into Datamapper (and Sinatra) and wonder about associations. Below are some of the models that I have. This is what I want to implement. I have a problem with Workoutitems and Workout. Workout will be managed separately, but Workoutitems has one workout associated with each line.

  • Training is just a list of training types (running, climbing, sitting, etc.).
  • The selected workout is the name of the workout set, along with the user's notes and the trainer. He has a collection of N workoutitems.
  • Workoutitems - this requires a workout and several repetitions that are part of the workout set.

      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
    
+4
source share
1 answer

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"])

+4
source

Source: https://habr.com/ru/post/1309657/


All Articles