所以我在这里有三个功能级别,课程,课程模块和课程练习。
但是,我想实现一些功能,使用户可以在课程完成时在课程模块上打勾,我以前确实有过这项工作,但是,这标志着所有用户的模块均已完成,而并非我想要的结果。
因此,我尝试了以下操作,在这里我建立了两个新表,一个用于courses_users
和course_modules_users
,以便我可以捕获课程用户并添加一条记录,以捕获用户ID,课程ID ,模块ID等,因此对于该用户来说是完全唯一的(因此,并不是所有用户都一样)
以下是与课程,课程模块和练习有关的架构:
ActiveRecord::Schema.define(version: 2018_09_12_115008) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
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.index ["course_id"], name: "index_course_modules_on_course_id"
t.index ["slug"], name: "index_course_modules_on_slug", unique: true
end
create_table "course_modules_users", force: :cascade do |t|
t.integer "course_module_id"
t.integer "user_id"
t.boolean "complete"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["course_module_id"], name: "index_course_modules_users_on_course_module_id"
t.index ["user_id"], name: "index_course_modules_users_on_user_id"
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.index ["slug"], name: "index_courses_on_slug", unique: true
end
create_table "courses_users", force: :cascade do |t|
t.integer "course_id"
t.integer "user_id"
t.boolean "complete"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["course_id"], name: "index_courses_users_on_course_id"
t.index ["user_id"], name: "index_courses_users_on_user_id"
end
end
这是新表的外观:
对于模型,我已执行以下操作:
course.rb
class Course < ApplicationRecord
extend FriendlyId
friendly_id :title, use: :slugged
has_many :course_modules
validates :title, :summary, :description, :trailer, :price, presence: true
def complete?
end
end
course_exercise.rb
class CourseExercise < ApplicationRecord
extend FriendlyId
friendly_id :title, use: :slugged
belongs_to :course_module
validates :title, :description, :video, :course_module_id, presence: true
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?
def complete?
end
private
def update_course
course.complete! if course.course_modules.all?(&:complete?)
end
end
course_modules_user.rb
class CourseModulesUser < ApplicationRecord
belongs_to :course_module
belongs_to :user
end
courses_user.rb
class CoursesUser < ApplicationRecord
belongs_to :course
belongs_to :user
end
对于控制器,我已执行以下操作:
courses / show.html.erb
<% if user_signed_in? %>
<section class="pt-4 px-8">
<section class="flex flex-wrap justify-between">
<h3 class="font-normal text-grey-dark mb-4 py-2">
<% if current_user.isAdmin? %>
<%= @course.title %>
<% else %>
<%= @course.title %> Modules
<% end %>
</h3>
<%= render 'layouts/dashboard/account' %>
</section>
</section>
<section class="px-8">
<% if Order.exists?(user_id: current_user.id, course_id: @course.id) %>
<% @course_modules.each do |course_module| %>
<section class="accordion-toggle">
<section class="w-full sm:pr-4 pb-4">
<section class="rounded shadow bg-grey-lighter border-b">
<section class="flex justify-between px-6 p-4">
<section class="flex items-center px-6 text-grey-darker">
<section class="font-bold text-base">
<%= course_module.title %>
</section>
</section>
<section class="flex items-center">
<% if user_signed_in? %>
<% if current_user.isAdmin? %>
<%= link_to "Edit", edit_course_module_path(course_module), class: "text-base text-grey-dark hover:text-darker px-4 py-2 border-2 border-grey leading-none no-underline hover:border-2 hover:border-grey-dark" %>
<% else %>
<% if course_module.complete? %>
<i class="fas fa-check text-green float-left mr-1"></i>
<span class="text-xs mr-2">Completed</span>
<% else %>
<%= link_to complete_course_module_path(course_module), method: :put do %>
<i class="fas fa-check text-grey-darkest float-left mr-2"></i>
<% end %>
<% end %>
<i class="flex items-center fal fa-angle-up"></i>
<% end %>
<% end %>
</section>
</section>
</section>
<section class="accordion-items hidden">
<% course_module.course_exercises.each do |exercise| %>
<section class="w-full">
<section class="rounded shadow bg-grey-lighter border-b">
<section class="flex justify-between px-6 p-4">
<section class="flex items-center px-6 text-grey-darker">
<section class="font-bold text-base pl-4">
- <%= exercise.title %>
</section>
</section>
<section>
<% if user_signed_in? %>
<% if current_user.isAdmin? %>
<%= link_to "Edit", edit_course_exercise_path(exercise), class: "text-base text-grey-dark hover:text-darker px-4 py-2 border-2 border-grey leading-none no-underline hover:border-2 hover:border-grey-dark" %>
<% else %>
<%= link_to "View Exercise", exercise, class: "text-base text-grey-dark hover:text-darker px-4 py-2 border-2 border-grey leading-none no-underline hover:border-2 hover:border-grey-dark" %>
<% end %>
<% end %>
</section>
</section>
</section>
</section>
<% end %>
</section>
</section>
</section>
<% end %>
<% else %>
<h3>You have not bought this course!</h3>
<%= form_with(url: '/payments/create') do |f| %>
<%= render partial: "stripe_checkout_button" %>
<%= hidden_field_tag(:course_id, @course.id) %>
<%= f.submit "Buy this course", class: "bg-blue hover:bg-blue-dark text-white font-semibold py-3 px-4 border-2 rounded-sm border-blue-dark shadow outline-none" %>
<% end %>
<% end %>
</section>
<% else %>
<section class="flex h-64 hero-banner p-4">
<section class="flex items-center mx-auto">
<h2 class="uppercase">
<%= @course.title %>
</h2>
</section>
</section>
<section class="pt-4 px-4">
<section class="w-full">
<section class="rounded overflow-hidden shadow">
<section style="padding: 56.25% 0 0 0; position: relative;">
<iframe src="https://player.vimeo.com/video/<%= @course.trailer %>" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</section>
</section>
</section>
<section class="flex flex-wrap -mx-4">
<section class="w-full lg:w-3/4 p-4">
<section class="bg-grey-lightest shadow text-grey-darker p-4">
<h2 class="font-normal mb-4">Course description</h2>
<p class="font-normal whitespace-pre-wrap"><%= @course.description %></p>
</section>
</section>
<section class="w-full lg:w-1/4 p-4">
<section class="bg-grey-lightest shadow text-grey-darker p-4 mb-4">
<h3 class="font-normal mb-4">Course Price</h3>
<p class="font-bold text-3xl text-green">£<%= @course.price %></p>
</section>
<%= link_to "Sign up to purchase", new_user_registration_path, class: "bg-blue hover:bg-blue-dark text-white font-semibold py-3 px-4 border-2 rounded-sm border-blue-dark shadow outline-none no-underline" %>
<section class="bg-grey-lightest shadow text-grey-darker py-4 px-4 mt-4">
<h3 class="font-normal mb-4">Course Modules</h3>
<% @course_modules.each do |course_module| %>
<section class="py-2 border-b-2 border-light modules">
<%= course_module.title %>
</section>
<% end %>
</section>
</section>
</section>
</section>
<% end %>
看看我是否知道模块是否完整,应该显示一个绿色的勾号,并且理想情况下,记录应该进入course_modules_users
表中,因为完成的字段应该将课程模块标记为{{ 1}}。
模型中的某些代码来自先前为所有用户标记课程模块的解决方案。
因此,如果我的想法正确,我只需要将当前功能移至新的true
方法中,并将数据捕获到新的数据库表中
但是,这对我来说是新事物,对任何知道如何进行此操作的帮助将非常感激。