4

Datamapper (および Sinatra) に飛び込んでいて、関連付けについて質問があります。以下は私が持っているいくつかのモデルです。これは私が実装したいものです。Workoutitems と Workout に問題があります。ワークアウトは個別に管理されますが、Workoutitems には各行に関連付けられた 1 つのワークアウトがあります。

  1. ワークアウト - ワークアウトの種類のリスト (ランニング、リフト、シットアップなど)
  2. 選択されたワークアウト - これは、一連のワークアウトの名前と、ユーザーとトレーナーによるメモです。N個のワークアウトアイテムのコレクションがあります
  3. Workoutitems - これには、ワークアウト セットに含まれるワークアウトとその反復回数が必要です。

    クラスワークアウト
      インクルード DataMapper::Resource
      プロパティ:id、シリアル #PK id
      property :name, String, :length=>50,:required=>true # ワークアウト名
      property :description, String, :length=>255 #ワークアウトの説明
    終わり
    
    
    class Selectedワークアウト
      インクルード DataMapper::Resource
      プロパティ:id、シリアル
      プロパティ :name, String, :length=>50, :required=>true
      プロパティ :workout_time, String, :length=>20
      プロパティ:user_notes、文字列、:length=>255
      プロパティ:coach_notes、文字列、:length=>255
      n, :workoutitems を持っています
    終わり
    
    クラスワークアウトアイテム
      インクルード DataMapper::Resource
      プロパティ:id、シリアル
      プロパティ:reps、文字列、:length=>50、:required=>true
      所属先:選択したワークアウト
    終わり
    
4

1 に答える 1

4

答える直前に、Ruby の一般的な規約 (すぐに説明する DataMapper に関連するもの) では、Selectedworkout や Workoutitems ではなく、SelectedWorkout や WorkoutItem などのクラス名を使用することを指摘しておきます。DataMapper はクラス名からリレーションシップに自動的に名前を付けるため、規則に従うと便利です。わかりにくい場合は申し訳ありませんが、回答の目的で、モデルの名前を変更できると仮定します。

Workout モデルが本質的に WorkoutItem からのデータの正規化されたコレクションであることを考えると、それをお勧めしますWorkoutItem.belongs_to(:workout)(ちなみに、これは IRB から実行できるコマンドであり、問​​題なく動作するかbelongs_to :workout、モデル クラスに貼り付けることができます)。もちろん)。

SelectedWorkout がデータへの主要なインターフェイスであるように思われるので、@user.selected_workouts.first.workout_items(最初に選択されたワークアウトのアイテムに対して) などと言うようなことをすると思います。

ちなみに、次の関係が設定されている場合は、さらに進んで Workout と SelectedWorkout の間の結合モデルとして WorkoutItem を使用できます。

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)

同様に、has many through 関係の反対側も同様に設定します。

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 に答える