使用单独的数据库迁移导轨设置has_many_through 5

时间:2018-08-23 11:15:40

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

因此,在课程,课程模块和课程练习中,我具有以下功能。

我有一个功能,当所有模块都完成后,用户可以在完成后标记模块。

但是,这适用于所有用户,而不是单个用户。因此,例如,当前正在发生的情况是,一个用户完成了该课程,当它被标记为完成时,但是如果我以第二位用户(尚未完成该课程)的身份登录,则它被标记为已完成。

根据我的研究,我相信我可以使用has_many_through关联来实现此目标,但是我不确定如何设置它。

到目前为止,这是我设置的方式。

schema.rb

create_table "course_exercises", force: :cascade do |t|
    t.string "title"
    t.text "description"
    t.string "video"
    t.integer "course_module_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "slug"
    t.index ["course_module_id"], name: "index_course_exercises_on_course_module_id"
    t.index ["slug"], name: "index_course_exercises_on_slug", unique: true
  end

  create_table "course_modules", force: :cascade do |t|
    t.string "title"
    t.integer "course_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "slug"
    t.boolean "complete", default: false, null: false
    t.index ["course_id"], name: "index_course_modules_on_course_id"
    t.index ["slug"], name: "index_course_modules_on_slug", unique: true
  end

  create_table "courses", force: :cascade do |t|
    t.string "title"
    t.text "summary"
    t.text "description"
    t.string "trailer"
    t.integer "price"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "slug"
    t.boolean "complete", default: false, null: false
    t.index ["slug"], name: "index_courses_on_slug", unique: true
  end

user.rb

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable, :confirmable,
         :recoverable, :rememberable, :trackable, :validatable

  has_one_attached :avatar

  has_many :courses

  def after_confirmation
    welcome_email
    super
  end

  protected

  def welcome_email
    UserMailer.welcome_email(self).deliver
  end
end

course.rb

class Course < ApplicationRecord
  extend FriendlyId
  friendly_id :title, use: :slugged

  has_many :users
  has_many :course_modules

  validates :title, :summary, :description, :trailer, :price, presence: true

  def complete!
    update_attribute(:complete, true)
  end
end

course_module.rb

class CourseModule < ApplicationRecord
  extend FriendlyId
  friendly_id :title, use: :slugged

  belongs_to :course
  has_many :course_exercises

  validates :title, :course_id, presence: true

  scope :completed, -> { where(complete: true) }
  after_save :update_course, if: :complete?

  private

  def update_course
    course.complete! if course.course_modules.all?(&:complete?)
  end
end

完整的模块

image

完成的课程

image

数据库:

课程

database

课程模块

database

但是如上所述,它已分配给所有用户,而不是单个用户。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

根据描述,似乎您将需要另一个表来 明智地捕获数据以显示完整的模块。

但是这里的另一个问题是您还需要捕获进度 当然会锻炼特定的用户,因此完成后 您可以更新course_module的所有练习。

注意:只有在用户完成以下操作后,才在下面提到的表中输入Enter 通过练习,我们还将获得rails提供的时间戳。

用户

has_many :courses, through: :user_courses
has_many :exercises, through: :user_course_exercise

UserCourseExercise

belongs_to :user
belongs_to :course_exercise
#table columns
user_id
exercise_id

如果特定课程的所有练习都包含在表格中,则将输入此表 完成。

UserCourse

belongs_to :user
belongs_to :course_exercise
#table columns
user_id 
course_id

拥有两个表的方法是当您需要显示练习时 对应于特定用户的数据,那么您将使用user_course_exercise 当需要完成课程时,请使用user_course表