使用者修改 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
再次執行測試,測試都通過了!