應觀眾要求,今天我們作一個管理後台,讓我們可以在網頁上管理關鍵字。
在開始之前,先大概說明一下今天要學習的範圍有哪些:
- 網頁的呈現需要使用 HTML 和 CSS
- 既然是後台,就要作登入功能
我們作的網站到目前為止沒有碰過任何的 HTML 和 CSS,突然要寫個管理後台也許會很吃力。不過還好是作後台,不需要多美觀。
使用產生器製作後台
幸好 Rails 有一個內建指令直接生成網頁,不一定要自己寫。
指令是 rails generate scaffold 資料模型名稱 和欄位們
rails g scaffold keyword_mapping channel_id keyword message --skip
後面的 --skip
是指定當發生衝突時應該略過。衝突的意思是指 rails 想新增一個檔案,剛好在目錄裡已經有個同名的檔案。
D:\只要有心,人人都可以作卡米狗\ironman>rails g scaffold keyword_mapping channel_id keyword message --skip
invoke active_record
skip db/migrate/20180115144538_create_keyword_mappings.rb
identical app/models/keyword_mapping.rb
invoke test_unit
identical test/models/keyword_mapping_test.rb
skip test/fixtures/keyword_mappings.yml
invoke resource_route
route resources :keyword_mappings
invoke scaffold_controller
create app/controllers/keyword_mappings_controller.rb
invoke erb
create app/views/keyword_mappings
create app/views/keyword_mappings/index.html.erb
create app/views/keyword_mappings/edit.html.erb
create app/views/keyword_mappings/show.html.erb
create app/views/keyword_mappings/new.html.erb
create app/views/keyword_mappings/_form.html.erb
invoke test_unit
create test/controllers/keyword_mappings_controller_test.rb
invoke helper
create app/helpers/keyword_mappings_helper.rb
invoke test_unit
invoke jbuilder
create app/views/keyword_mappings/index.json.jbuilder
create app/views/keyword_mappings/show.json.jbuilder
create app/views/keyword_mappings/_keyword_mapping.json.jbuilder
invoke test_unit
create test/system/keyword_mappings_test.rb
invoke assets
invoke coffee
create app/assets/javascripts/keyword_mappings.coffee
invoke scss
create app/assets/stylesheets/keyword_mappings.scss
invoke scss
create app/assets/stylesheets/scaffolds.scss
D:\只要有心,人人都可以作卡米狗\ironman>
以下說明到底生成了什麼東西。
生成 Routes
他會在 config/routes.rb
生成一個 resource:
resources :keyword_mappings
這是資源(resource),提供一個資源的存取所需要的網址和 Controller 的對應。
這行會生成 8 組網址與 7 個 Controller Action 的對應,可以使用 rails routes
觀察:
D:\只要有心,人人都可以作卡米狗\ironman>rails routes
Prefix Verb URI Pattern Controller#Action
keyword_mappings GET /keyword_mappings(.:format) keyword_mappings#index
POST /keyword_mappings(.:format) keyword_mappings#create
new_keyword_mapping GET /keyword_mappings/new(.:format) keyword_mappings#new
edit_keyword_mapping GET /keyword_mappings/:id/edit(.:format) keyword_mappings#edit
keyword_mapping GET /keyword_mappings/:id(.:format) keyword_mappings#show
PATCH /keyword_mappings/:id(.:format) keyword_mappings#update
PUT /keyword_mappings/:id(.:format) keyword_mappings#update
DELETE /keyword_mappings/:id(.:format) keyword_mappings#destroy
kamigo_eat GET /kamigo/eat(.:format) kamigo#eat
kamigo_request_headers GET /kamigo/request_headers(.:format) kamigo#request_headers
kamigo_request_body GET /kamigo/request_body(.:format) kamigo#request_body
kamigo_response_headers GET /kamigo/response_headers(.:format) kamigo#response_headers
kamigo_response_body GET /kamigo/response_body(.:format) kamigo#show_response_body
kamigo_sent_request GET /kamigo/sent_request(.:format) kamigo#sent_request
kamigo_webhook POST /kamigo/webhook(.:format) kamigo#webhook
7 個 Action 分別為 index, create, new, edit, show, update, destroy,接下來說明各個 Action 的功能:
以下屬於 GET request,這些都是網頁:
- index:列表頁
- new:新增資料頁
- show:檢視資料頁
- edit:編輯資料頁
以下非 GET request,都是請求資料變更:
- create:請求新增資料
- update:請求更新資料
- destroy:請求刪除資料
生成 Controller
生成了一個 Controller 在:app/controllers/keyword_mappings_controller.rb
。7 個對應的 Action 都寫好了,這裡就不多介紹。
生成 View
生成了一整個資料夾的 View,其中最重要的 4 個:
app/views/keyword_mappings/index.html.erb
app/views/keyword_mappings/edit.html.erb
app/views/keyword_mappings/show.html.erb
app/views/keyword_mappings/new.html.erb
這就是那些 GET request 會用到的網頁檔,也都寫好了。
實測
既然都寫好了就來試用看看,先執行網頁伺服器:
rails s
然後開啟網頁 http://localhost:3000/keyword_mappings:
index 列表頁
new 新增資料頁
隨便亂填:
show 檢視資料頁
所以其實不考慮美觀性的話,其實後台只要一個指令就完成了。
建立登入功能
使用知名套件 devise 來作。
我相信現在的你如果沒有英文閱讀障礙,應該已經能看懂這個使用說明。
總而言之先在 Gemfile 加這行:
gem 'devise'
然後在小黑框打 bundle install
安裝套件。
裝好之後使用 devise 提供的產生器指令進行初始化: rails generate devise:install
。
D:\只要有心,人人都可以作卡米狗\ironman>rails generate devise:install
create config/initializers/devise.rb
create config/locales/devise.en.yml
===============================================================================
Some setup you must do manually if you haven't yet:
1. Ensure you have defined default url options in your environments files. Here
is an example of default_url_options appropriate for a development environment
in config/environments/development.rb:
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
In production, :host should be set to the actual host of your application.
2. Ensure you have defined root_url to *something* in your config/routes.rb.
For example:
root to: "home#index"
3. Ensure you have flash messages in app/views/layouts/application.html.erb.
For example:
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
4. You can copy Devise views (for customization) to your app by running:
rails g devise:views
===============================================================================
D:\只要有心,人人都可以作卡米狗\ironman>
他說有幾個步驟產生器沒搞頭,必須手動進行。我們先不管他,等到真正出問題再回頭來解決。
使用產生器產生用戶資料模型:
rails generate devise user
D:\只要有心,人人都可以作卡米狗\ironman>rails generate devise user
invoke active_record
create db/migrate/20180115152537_devise_create_users.rb
create app/models/user.rb
invoke test_unit
create test/models/user_test.rb
create test/fixtures/users.yml
insert app/models/user.rb
route devise_for :users
D:\只要有心,人人都可以作卡米狗\ironman>
跟剛剛的 scaffold 差不多,該生的都生好了。
註冊頁:http://localhost:3000/users/signup 登入頁:http://localhost:3000/users/signin
關閉註冊功能
我們要將註冊功能關閉,如果大家都能註冊,那還要後台幹嘛?
在 app/models/user.rb
:
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
刪除 :registerable,
:
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable,
:recoverable, :rememberable, :trackable, :validatable
end
登入後才能管理關鍵字
我們希望只有登入後的人才能進入管理關鍵字的頁面。
在 app/controllers/keyword_mappings_controller.rb
加入:
before_action :authenticate_user!
看起來像這樣:
class KeywordMappingsController < ApplicationController
before_action :authenticate_user!
before_action :set_keyword_mapping, only: [:show, :edit, :update, :destroy]
...下略
這時候開啟網址:http://localhost:3000/keyword_mappings,就會因為尚未登入,而被引導至登入頁。
發布流程
- 上傳程式碼
- Heroku 上的資料庫遷移
關閉了註冊功能後要怎麼新增自己的帳號?
使用 rails console
連上去新增帳號:
heroku run rails console
連上後會是 rails console
的樣子:
D:\只要有心,人人都可以作卡米狗\ironman>heroku run rails console
Running rails console on people-all-love-kamigo... up, run.2165 (Free)
Loading production environment (Rails 5.1.4)
irb(main):001:0>
寫一行程式碼新增資料:
User.create(email:'kamigo.service@gmail.com', password:'kamigo')
會有一些 SQL 的訊息:
irb(main):001:0> User.create(email:'kamigo.service@gmail.com', password:'kamigo')
D, [2018-01-15T15:42:28.307402 #4] DEBUG -- : (6.0ms) BEGIN
D, [2018-01-15T15:42:28.313291 #4] DEBUG -- : User Exists (2.1ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = $1 LIMIT $2 [["email", "kamigo.service@gmail.com"], ["LIMIT", 1]]
D, [2018-01-15T15:42:28.317361 #4] DEBUG -- : SQL (1.9ms) INSERT INTO "users" ("email", "encrypted_password", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["email", "kamigo.service@gmail.com"], ["encrypted_password", "$2a$11$EyR.yuDYI3J2s9/Q8Etk5evQzsz2bGAPdvdcr.xmFQbzYbBPQk/kK"], ["created_at", "2018-01-15 15:42:28.313883"], ["updated_at", "2018-01-15 15:42:28.313883"]]
D, [2018-01-15T15:42:28.320139 #4] DEBUG -- : (2.0ms) COMMIT
=> #<user id:="" 1,="" email:="" "kamigo.service@gmail.com",="" created_at:="" "2018-01-15="" 15:42:28",="" updated_at:="" 15:42:28"="">
irb(main):002:0>
看到倒數第二行:
=> #<user id:="" 1,="" email:="" "kamigo.service@gmail.com",="" created_at:="" "2018-01-15="" 15:42:28",="" updated_at:="" 15:42:28"="">
就表示建立好帳號了。
線上實測
https://people-all-love-kamigo.herokuapp.com/keyword_mappings:
大家可以用我的帳號登入看看。
帳號:kamigo.service@gmail.com 密碼:kamigo
本日重點
- 學會使用 scaffold
- 學會作登入系統
你們可以透過閱讀 scaffold 產生出來的程式碼來學習 HTML 和 Controller Action 的寫法。這跟學英文一樣,看到不懂的單字就 Google,這單字量還比英文少超多,大概 100~200 個字而已。
明天講怎麼發公告。
沒有留言:
張貼留言