Browse Source

Add Course model with participations

Frans Bergman 7 năm trước cách đây
mục cha
commit
6339c8ea52

+ 21 - 0
app/models/course.rb

@@ -0,0 +1,21 @@
+class Course < ApplicationRecord
+  belongs_to :school
+  validates :school_id, presence: true
+
+  validates :name, presence: true, length: { maximum: 255 }
+
+  validates :starts_on, presence: true
+  validates :ends_on, presence: true
+  validate :date_order
+
+  has_many :course_participations, dependent: :destroy
+  has_many :users, through: :course_participations
+
+
+  private
+    def date_order
+      if ends_on < starts_on
+        errors.add(:ends_on, "should come after starts_on")
+      end
+    end
+end

+ 11 - 0
app/models/course_participation.rb

@@ -0,0 +1,11 @@
+class CourseParticipation < ApplicationRecord
+  belongs_to :course
+  belongs_to :user
+  validates :course_id, presence: true
+  validates :user_id, presence: true
+
+  enum role: [:student, :teacher]
+
+  scope :teachers, -> { where(role: :teacher) }
+  scope :students, -> { where(role: :student) }
+end

+ 2 - 0
app/models/school.rb

@@ -5,5 +5,7 @@ class School < ApplicationRecord
   has_many :administrators, through: :administrations,
                             class_name: "User", source: :user
 
+  has_many :courses
+
   has_many :users
 end

+ 12 - 0
db/migrate/20180219101748_create_courses.rb

@@ -0,0 +1,12 @@
+class CreateCourses < ActiveRecord::Migration[5.1]
+  def change
+    create_table :courses do |t|
+      t.string :name
+      t.belongs_to :school, foreign_key: true
+      t.date :starts_on
+      t.date :ends_on
+
+      t.timestamps
+    end
+  end
+end

+ 13 - 0
db/migrate/20180219151405_create_course_participations.rb

@@ -0,0 +1,13 @@
+class CreateCourseParticipations < ActiveRecord::Migration[5.1]
+  def change
+    create_table :course_participations do |t|
+      t.belongs_to :course, foreign_key: true
+      t.belongs_to :user, foreign_key: true
+      t.integer :role
+
+      t.timestamps
+    end
+
+    add_index :course_participations, [:user_id, :course_id], unique: true
+  end
+end

+ 22 - 1
db/schema.rb

@@ -10,7 +10,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema.define(version: 20180210170344) do
+ActiveRecord::Schema.define(version: 20180219151405) do
 
   create_table "administrations", force: :cascade do |t|
     t.integer "user_id"
@@ -37,6 +37,27 @@ ActiveRecord::Schema.define(version: 20180210170344) do
     t.datetime "updated_at", null: false
   end
 
+  create_table "course_participations", force: :cascade do |t|
+    t.integer "course_id"
+    t.integer "user_id"
+    t.integer "role"
+    t.datetime "created_at", null: false
+    t.datetime "updated_at", null: false
+    t.index ["course_id"], name: "index_course_participations_on_course_id"
+    t.index ["user_id", "course_id"], name: "index_course_participations_on_user_id_and_course_id", unique: true
+    t.index ["user_id"], name: "index_course_participations_on_user_id"
+  end
+
+  create_table "courses", force: :cascade do |t|
+    t.string "name"
+    t.integer "school_id"
+    t.date "starts_on"
+    t.date "ends_on"
+    t.datetime "created_at", null: false
+    t.datetime "updated_at", null: false
+    t.index ["school_id"], name: "index_courses_on_school_id"
+  end
+
   create_table "messages", force: :cascade do |t|
     t.integer "user_id"
     t.integer "conversation_id"

+ 7 - 0
db/seeds.rb

@@ -47,3 +47,10 @@ ConversationParticipation.create!(conversation: conversation, user: user)
   content = Faker::Lorem.sentence(10)
   Message.create!(user: user, conversation: conversation, content: content)
 end
+
+10.times do |n|
+  name = Faker::Educator.course
+  course = Course.create!(school: school, name: name, starts_on: DateTime.now, ends_on: 6.months.since)
+  CourseParticipation.create!(course: course, user: user, role: :teacher)
+  CourseParticipation.create!(course: course, user: User.find(2), role: :student)
+end

+ 11 - 0
test/fixtures/course_participations.yml

@@ -0,0 +1,11 @@
+# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+one:
+  course: one
+  user: daniel
+  role: teacher
+
+two:
+  course: one
+  user: billy
+  role: student

+ 13 - 0
test/fixtures/courses.yml

@@ -0,0 +1,13 @@
+# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+one:
+  name: Programming 1
+  school: one
+  starts_on: 2018-02-19
+  ends_on: 2018-02-19
+
+two:
+  name: English 2
+  school: two
+  starts_on: 2018-02-19
+  ends_on: 2018-02-19

+ 18 - 0
test/models/course_participation_test.rb

@@ -0,0 +1,18 @@
+require 'test_helper'
+
+class CourseParticipationTest < ActiveSupport::TestCase
+  def setup
+    @participation = course_participations(:one)
+    @user = users(:daniel)
+    @course = courses(:one)
+  end
+
+  test "should be valid" do
+    assert @participation.valid?
+  end
+
+  test "should filter by role correctly" do
+    filtered = @course.users.merge(CourseParticipation.teachers)
+    assert_equal filtered, [@user]
+  end
+end

+ 23 - 0
test/models/course_test.rb

@@ -0,0 +1,23 @@
+require 'test_helper'
+
+class CourseTest < ActiveSupport::TestCase
+
+  def setup
+    @course = courses(:one)
+  end
+
+  test "should be valid" do
+    assert @course.valid?
+  end
+
+  test "name should be present" do
+    @course.name = "        "
+    assert_not @course.valid?
+  end
+
+  test "dates should be in order" do
+    @course.starts_on = 1.days.ago
+    @course.ends_on = 2.days.ago
+    assert_not @course.valid?
+  end
+end