6. 實作用戶更新資料 API
6-1 目標
這一章我們實作兩個有關用戶的 API:
PATCH /me
更新自己的資料,包括修改 E-mail、密碼和上傳照片GET /me
查詢自己的資料
目的是處理檔案上傳的情況。
6-2 修改個人資料(照片檔案上傳)
修改 Gemfile
,加上
# ...(略)
+ gem 'carrierwave'
+ gem 'mini_magick'
執行 bundle
然後重啟伺服器
執行 rails g uploader avatar
執行 rails g migration add_avatar_to_users avatar:string
執行 rake db:migrate
編輯 app/uploaders/avatar_uploader.rb
增加不同縮圖的情況:
class AvatarUploader < CarrierWave::Uploader::Base
+
+ include CarrierWave::MiniMagick
+
storage :file
+
+ process resize_to_fit: [800, 800]
+
+ version :thumb do
+ process resize_to_fill: [200,200]
+ end
+
+ version :medium do
+ process resize_to_fill: [400,400]
+ end
+
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
end
編輯 app/models/user.rb
,新增一行:
+ mount_uploader :avatar, AvatarUploader
編輯 config/routes.rb
,加入
namespace :api, :defaults => { :format => :json } do
namespace :v1 do
+ get "/me" => "users#show", :as => :user
+ patch "/me" => "users#update", :as => :update_user
# ...(略)
執行 rails g controller api::v1::users --no-assets
編輯 app/controllers/api/v1/users_controller.rb
- class Api::V1::UsersController < ApplicationController
+ class Api::V1::UsersController < ApiController
+ before_action :authenticate_user!
+
+ def update
+ if current_user.update(user_params)
+ render :json => { :message => "OK" }
+ else
+ render :json => { :message => "Failed", :errors => + current_user.errors }, :status => 400
+ end
+ end
+
+ protected
+
+ def user_params
+ params.permit(:email, :password, :avatar)
+ end
end
用 Postman 上傳照片看看
注意到 Postman 選用 POST 時,還可以選 request 的資料格式。雖然我們講 Web API 常用 JSON 格式,但這只是說 response 的資料格式用 JSON。客戶端的 HTTP request 資料格式不一定是 JSON。而 request 也是有不同種資料格式,其中只有
form-data
才能上傳檔案。詳細的原理可以參考 四種常見的 POST 提交數據方式
6-3 查詢個人資料
編輯 app/controllers/api/v1/users_controller.rb
# ...(略)
+ def show
+ render :json => {
+ :email => current_user.email,
+ :avatar => current_user.avatar,
+ :updated_at => current_user.updated_at,
+ :created_at => current_user.created_at
+ }
+ end
瀏覽器瀏覽 http://localhost:3000/api/v1/me?auth_token=FYN27sLKKCNt4LhTH5or