【问题标题】:Setting up Rails has-many-through association设置 Rails has-many-through 关联
【发布时间】:2016-12-26 14:51:24
【问题描述】:

我有四个模型:

  • User
  • Exercise
  • Result
  • UsersExercise

我正在尝试在模型之间建立关联,这使我可以做出如下 ORM 语句:

User.first.exercises.first.barbell_push

我想要得到的是每个exercise 对应User,然后得到一个barbell_push 结果。

以下是我目前的模型和关联:


UsersExercise

表:

create_table :users_exercises do |t|
  t.integer :user_id
  t.integer :exercise_id
  t.date :date
  t.timestamps null: false
end

型号:

class UsersExercise < ActiveRecord::Base
  belongs_to :user
  belongs_to :exercise
end

Exercise

表:

create_table :exercises do |t|
  t.integer :dead_lift_id
  t.integer :barbel_push_id
  t.integer :dumbbels_curl_id
  t.timestamps null: false
end

型号:

class Exercise < ActiveRecord::Base
  has_many :dead_lift, class_name: 'Result', foreign_key: 'exercise_id'
  has_many :barbel_push, class_name: 'Result', foreign_key: 'exercise_id'
  has_many :dumbbell_curl, class_name: 'Result', foreign_key: 'exercise_id'
  has_many :users_exercises, dependent: :destroy
  has_many :users, through: :users_exercises
end

Result

表:

create_table :results do |t|
  t.integer :reps
  t.integer :weight
  t.integer :exercise_id
  t.timestamps null: false
end

型号:

class Result < ActiveRecord::Base
  belongs_to :exercise
end

User

型号:

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable, :recoverable, :rememberable,
         :trackable, :validatable, :confirmable, :omniauthable, :omniauth_providers => [:google_oauth2]
  ROLES = [:admin, :user, :trainer, :dietician]
  has_many :sent_messages, :class_name => "Message", :foreign_key => "sender_id"
  has_many :received_messages, :class_name => "Message", :foreign_key => "receiver_id"
  has_many :users_exercises
  has_many :exercise, through: :users_exercises
end

【问题讨论】:

    标签: ruby-on-rails ruby associations has-many-through


    【解决方案1】:

    我认为你只需要一张表(你已经有 :users)

    create_table :exercises do |t|
      t.integer :user_id
      t.string :name
      t.integer :weight
      t.integer :reps
      t.date :check_in_time
      t.date :check_out_time
      t.timestamps null: false
     end
    

    “名称”列将是 barbell_push、dumbell_curl 等,它们是从表单中的集合字段中获取的。当从一个练习转移到另一个练习时,这将需要 check_in 和 check_out,但这应该非常简单。有了这个你确实可以得到:

    @user.barbell_push.date
    @user.barbell_push.duration (time elapsed from check-in to check-out)
    @user.barbell_push.reps
    @user.barbell_push.weight
    @user.dumbell_curl.reps
    etc in whatever sequence you want to present the data.
    

    【讨论】:

    • 谢谢。对不起,你一直等到新年,但我有很多事情要做。我会按照你描述的方式保留我的桌子!干杯!