iT邦幫忙

2021 iThome 鐵人賽

DAY 25
0
自我挑戰組

初級紅寶石魔法師心得分享。系列 第 25

D-5.Rails route scope

Routes

其實路經身為整個MVCController的門面,卻容易被輕忽對待,即使遵照著TDD的概念去開發,可能也會因為不好的習慣,有了多餘的路徑。
因為resource太方便了

雖然多了一些路徑不一定對使用上會有影響,但家裡多了沒有用處的門,還是會怕怕的。
從前幾日的基礎API練習中,也可以知道,如果有多的路徑,可能就會發生我們原本沒預計要有的操作發生。所以DRY過的路徑對API開發也非常重要。

所以來複習一下,保持好習慣,永遠都讓routes.rbDRY


快速複習Routes


首頁選擇

Rails.application.routes.draw do
  root 'welcome#index'
end

對應產生資料。


指定轉址

Rails.application.routes.draw do
  get "/roles" => redirect("/players")
end

對應產生資源。

也可運用在自製短網址。


依照REST建立各路徑。

Rails.application.routes.draw do
  get '/products', to: 'products#index'
  post '/products', to: 'products#create'
  get '/products/:id', to: 'products#show'
  patch '/products/:id', to: 'products#update'
  delete '/products/:id', to: 'products#destroy'
end

對應產生資料。

依照REST去編寫路徑,對RESTful API開發很重要,只給規定的通道,規定能做的事。


利用resourcesresource製造路徑。

resources:對複數資源使用。
resource :對只有單數資源使用。

Rails.application.routes.draw do
  resources :roles
end

對應產生資源。

用了resources後面名詞接單數不影響,但請依照Rails慣例使用,複數就用複數名詞。

Rails.application.routes.draw do
  resource :boss
end

對應產生資源。

resource後面名詞接複數,很頑皮,但也不影響,就沒辦法依照:id單項處理,想處理複數資源就該用resources

可以利用onlyexpect來限定

Rails.application.routes.draw do
  resources :products, only: [:index, :show]
  #只開index與show,其他都不要。
  resources :roles, expect: [:index, :show]
  #不要index與show,其他都要。
end

collectionmember、與巢狀設計。

collection:如果對資源全體有的其它需求時適合使用。

Rails.application.routes.draw do
  resources :roles do
    collection do
      get :job_warrior
    end
  end
end

例如有頁面想查Role中是戰士的資料,roles/job_warrior
產生資源。

member : 如果對資源中單一項目或特定項目有其它action時適合使用。

Rails.application.routes.draw do
  resources :roles do
    member do
      get :jobs
      post :job
      delete :job
    end
  end
end

roles/2/jobsroles/2/job
產生資源

可以看到會把:id帶進去網址,可以更明確知道在對哪一個項目做操作。

若只有單一action可以不用block寫。
例如:

Rails.application.routes.draw do
  resources :roles do
    get :jobs, on: :member
  end
end

當然也可以resourcesresources

Rails.application.routes.draw do
  resources :roles do
    resources :jobs, only: [:show, :destroy]
  end
end

可以產出roles/1/jobs/2這樣的網址。
產生資源

可以很巢,但這樣不是很潮。

例如:

Rails.application.routes.draw do
  resources :roles do
    resources :jobs do
      resources :skills do
        resource :power
    end
  end
end

會這樣,不只路徑長,到時要轉址,要找帶給路徑的值會找不完。


Scopenamespace

是的Routes也有scope,但是先認識namespace
namespace可以幫你指定的資源加上字首(前綴),並使用指定modulecontroller,並協助產生絕對路徑。

Rails.application.routes.draw do
  resources :roles  #這組產生的資源就不看了。
  namespace :gm do
    resources :roles
  end
end

產生資源。

可以發現/roles前面都多了gm,這被多利用在建立後台系統,當然如果沒有建立好完善認證制度,後台就少用admin這種好猜到的。

Scope的用意在更精準的調整你想做的事
想要更多客製化選項的人用的
有三個選項modulepathas

不加任何選項。

Rails.application.routes.draw do
  scope :gm do
    resources :roles
  end
end

產生資源。

可以發現跟namespace非常像,沒選項一樣為路徑加上前綴,不同的地方是使用的controller一樣是roles而不是gm/rolespath/url未更動。

選項module

Rails.application.routes.draw do
  scope module: 'gm' do
    resources :roles
  end
end

產生資源。

與沒有選項相比。路徑前綴沒了,但是必須用位於指定module的controller。(gm/roles)

選項path

Rails.application.routes.draw do
  scope module: 'gm', path: 'admin' do
    resources :roles
  end
end

產生資源。

路徑前綴自定義,用哪個controller自定義,還是path/url未更動。

選項as
更動path/url

Rails.application.routes.draw do
  scope module: 'gm', path: 'admin', as: 'gogo' do
    resources :roles
  end
end

產生資源

可以看到,當有需求可以用scope來更精準控制。
太麻煩就直接namespace啦!

在路徑設定上,是一個新手容易不注重的區塊,但有好的門牌號碼與路徑規劃,對controller設計上也會有好的影響,希望自己不要再用resources來解決一切了。


上一篇
D-6. Model scope & 建立搜索功能
下一篇
D-4.Line_pay_api 串接(一)
系列文
初級紅寶石魔法師心得分享。30

尚未有邦友留言

立即登入留言