4

我只是深入研究 Datamapper(和 Sinatra),并有一个关于关联的问题。下面是我的一些模型。这就是我想要实现的。我对锻炼项目和锻炼有疑问。锻炼将单独管理,但锻炼项目有一个与每一行关联的锻炼。

  1. 锻炼 - 只是锻炼类型的列表(跑步、举重、仰卧起坐等)
  2. 选定的锻炼 - 这是一组锻炼的名称,以及用户和培训师的注释。它有 N 个锻炼项目的集合
  3. 锻炼项目 - 这需要进行锻炼并在锻炼集中进行多次重复。

    课堂锻炼
      包括 DataMapper::Resource
      属性:id,序列号#PK id
      property :name, String, :length=>50,:required=>true # 锻炼名称
      属性 :description, String, :length=>255 #workout 描述
    结尾
    
    
    类Selectedworkout
      包括 DataMapper::Resource
      属性:id,序列号
      属性 :name, String, :length=>50, :required=>true
      属性 :workout_time, 字符串, :length=>20
      属性 :user_notes, 字符串, :length=>255
      属性:coach_notes,字符串,:长度=> 255
      有 n, :workoutitems
    结尾
    
    类锻炼项目
      包括 DataMapper::Resource
      属性:id,序列号
      属性 :reps, String, :length=>50, :required=>true
      属于_to :selectedworkout
    结尾
    
4

1 回答 1

4

就在我回答之前,我要指出典型的 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"])

于 2010-05-13T17:59:09.793 回答