使用者修改 course 的話,必須是當初創作者才可以修改

接著我們要實現,只有當初建立 course 的 user 才可以修改 course。

首先按照下面修改 spec/controllers/courses_controller_spec.rb

diff --git a/spec/controllers/courses_controller_spec.rb b/spec/controllers/courses_controller_spec.rb
index 4190bfa..41ad426 100644
--- a/spec/controllers/courses_controller_spec.rb
+++ b/spec/controllers/courses_controller_spec.rb
@@ -113,23 +113,39 @@ RSpec.describe CoursesController, type: :controller do
   end

   describe "GET edit" do
-    let(:user) { create(:user) }
-    before { sign_in user }
+    let(:author) { create(:user) }
+    let(:not_author) { create(:user) }

-    it "assign course" do
-      course = create(:course)
+    context "signed in as author" do
+      before { sign_in author }

-      get :edit, params: { :id => course.id }
+      it "assigns course" do
+        course = create(:course, user: author)

-      expect(assigns[:course]).to eq(course)
+        get :edit, params: { :id => course.id }
+
+        expect(assigns[:course]).to eq(course)
+      end
+
+      it "renders template" do
+        course = create(:course, user: author)
+
+        get :edit, params: { :id => course.id }
+
+        expect(response).to render_template("edit")
+      end
     end

-    it "render template" do
-      course = create(:course)
+    context "signed in not as author" do
+      before { sign_in not_author }

-      get :edit, params: { :id => course.id }
+      it "raises an error" do
+        course = create(:course, user: author)

-      expect(response).to render_template("edit")
+        expect do
+          get :edit, params: { :id => course.id }
+        end.to raise_error ActiveRecord::RecordNotFound
+      end
     end
   end

跑測試發現:

$ rspec spec/controllers/courses_controller_spec.rb
..............F........

Failures:

  1) CoursesController GET edit signed in not as author raises an error
     Failure/Error:
       expect do
         get :edit, params: { :id => course.id }
       end.to raise_error ActiveRecord::RecordNotFound

       expected ActiveRecord::RecordNotFound but nothing was raised
     # ./spec/controllers/courses_controller_spec.rb:145:in `block (4 levels) in <top (required)>'

Finished in 0.32925 seconds (files took 1.8 seconds to load)
23 examples, 1 failure

Failed examples:

rspec ./spec/controllers/courses_controller_spec.rb:142 # CoursesController GET edit signed in not as author raises an error

這是因為在 edit action 我們查找 course 是用

Course.find(params[:id])

應該要限制在 user 的 courses 查找才對,修改 app/controllers/courses_controller.rb

diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb
index 78f4d78..8fe5ad6 100644
--- a/app/controllers/courses_controller.rb
+++ b/app/controllers/courses_controller.rb
@@ -25,7 +25,7 @@ class CoursesController < ApplicationController
   end

   def edit
-    @course = Course.find(params[:id])
+    @course = current_user.courses.find(params[:id])
   end

   def update

再次運行測試:

rspec spec/controllers/courses_controller_spec.rb
............FFF........

Failures:

  1) CoursesController GET edit signed in as author assigns course
     Failure/Error: @course = current_user.courses.find(params[:id])

     NoMethodError:
       undefined method `courses' for #<User:0x007fd05539e360>

  2) CoursesController GET edit signed in as author renders template
     Failure/Error: @course = current_user.courses.find(params[:id])

     NoMethodError:
       undefined method `courses' for #<User:0x007fd05532c080>

  3) CoursesController GET edit signed in not as author raises an error
     Failure/Error:
       expect do
         get :edit, params: { :id => course.id }
       end.to raise_error ActiveRecord::RecordNotFound

       expected ActiveRecord::RecordNotFound, got #<NoMethodError: undefined method `courses' for #<User:0x007fd05595d468>> with backtrace:

Finished in 0.34986 seconds (files took 2.02 seconds to load)
23 examples, 3 failures

user 並沒有定義 courses 方法!當一個 Model 定義了 has_many 關聯時,會自動幫我們加上這個方法

幫 User model 加上 has_many :courses 關聯,修改 app/models/user.rb

diff --git a/app/models/user.rb b/app/models/user.rb
index b2091f9..ba9e16d 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -3,4 +3,6 @@ class User < ApplicationRecord
   # :confirmable, :lockable, :timeoutable and :omniauthable
   devise :database_authenticatable, :registerable,
          :recoverable, :rememberable, :trackable, :validatable
+
+  has_many :courses
 end

以及相對應的 spec,修改 spec/models/user_spec.rb

diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 47a31bb..047f2bc 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -1,5 +1,5 @@
-require 'rails_helper'
+require "rails_helper"

-RSpec.describe User, type: :model do
-  pending "add some examples to (or delete) #{__FILE__}"
+RSpec.describe User do
+  it { is_expected.to have_many(:courses) }
 end

再次執行測試,測試都通過了!

results matching ""

    No results matching ""