---
# System prepended metadata

title: Route

---

# Route
Route是決定你網址路徑的對照表，他會決定你要往哪個controller還有往哪個action

Rails會根據```config/routes.rb```決定會有什麼樣的路徑。
但也有非Route決定的網頁，Public檔案存放的就是非Route路徑的網頁，裡面有404.html這種找不到網頁或者是網站壞掉時用的頁面。

## routes.rb的寫法

假設你的網頁首頁是http://localhost:3000/

```ruby
Rails.application.routes.draw do
  get "/", to: "welcome#home"
end
```
這時候會將網頁首頁換成welcome_controller的index這個action所對應的view/welcome/index_html.erb這個檔案的畫面。

另外設定首頁畫面也能這樣寫
```ruby
Rails.application.routes.draw do
  root "welcome#home"
end
```


---


```ruby
Rails.application.routes.draw do
  get "/about", to: "pages#about"
end
```
http://localhost:3000/about 這個網頁會導向pages_controller的about action所對應的view




---
```ruby
Rails.application.routes.draw do
  post '/blog/:id', to: 'blog#create'
# id是變數，可以依照需求設定變數，例如:a,:b,：cat,:handler 等等   
end
```
除了get以外，也可以使用其他ＲＥＳＴ語法。

* GET 讀取資源
* PUT 替換資源
* PATCH 更換資源部分內容
* DELETE 刪除資源
* OPTIONS 回傳該資源所支援的所有 HTTP 請求方法
* CONNECT 將連線請求轉換至 TCP/IP 隧道
* POST 新增資源

---
### 轉址
Route 除了做路徑對照外，也可以直接做轉址：
```ruby
Rails.application.routes.draw do
  get '/users', to: redirect('/accounts')
end
```
只要到了/users就會自動轉到/accounts的位置，除了站內的網址也可以設定轉往站外

```ruby
Rails.application.routes.draw do
  get '/users',to: redirect('https://google.com')
end
```
只要到了/users就會自動轉去google網頁

---
### resources/resource
Rails 也有讓你可以快速開出八條常用路徑的方法。

```ruby
Rails.application.routes.draw do
  resources :users
end
```
想要看現在有什麼路徑可以在終端機輸入
```
$rails routes
```
如果想要縮小範圍只找users的路徑
```
$rails routes -c users
```
![](https://i.imgur.com/xKgzpoy.png)


---

如果你不想要你的網址有id的話，少打一個s變成resource
```ruby
Rails.application.routes.draw do
  resource :users
end
```
![](https://i.imgur.com/UUTTnw8.png)

單數的路徑除了沒有帶有 id 之外，也沒有**index**



---
### 如果我覺得八條路徑太多了，不想要這麼多怎麼辦？
**我想要index,new,create這三個action的路徑就好**
```ruby
Rails.application.routes.draw do
  resources :users,only: [:index, :new, :create]
end
```

---

**我只想要show這個acion的路徑**
```ruby
Rails.application.routes.draw do
  resources :users,except: [:show]
end
```


---
## 這八個路徑不夠用，我還想增加該怎麼辦？

如果我想要多一個/users/sign_for的路徑

```ruby
Rails.application.routes.draw do    
  resource :users do
    get :sign_for
  end  
end
```

我不想要new，我想要叫sign_for
```ruby
Rails.application.routes.draw do    
  resource :users,except: [:new] do
    get :sign_for
  end  
end
```
resources跟resource的差別
```
resources :cats do
  get :food
end
```
![](https://i.imgur.com/8r8jk2u.png)

```
resource :cats do
  get :food
end
```
![](https://i.imgur.com/IL0jNNn.png)

resources會生出一個:cat_id，但是會跟:id容易搞混

---

在Resources會使用member與collection

member與collection的差別是member的路徑有:id，collection沒有。
```ruby
Rails.application.routes.draw do    
  resources :users,except: [:new] do
    member do
      get :sign_for
    end
  end  
end
```
![](https://i.imgur.com/CUPMmbD.png)

```ruby
Rails.application.routes.draw do    
  resources :users,except: [:new] do
    collection do
      get :sign_for
    end
  end  
end
```
![](https://i.imgur.com/78o4gOc.png)


---
## Namespace
我想要在/users前面多一段/api
http://localhost:3000/api/users
```ruby
Rails.application.routes.draw do
  namespace :api do
    resources :users
  end
end
```
![](https://i.imgur.com/qXG8nLY.png)


---
#### shallow

```ruby
Rails.application.routes.draw do
  resources :dogs,except: [:index,:new,:create]

  resources :cats do
    resources :dogs,only: [:index,:new,:create]
  end
end
```
使用shallow可以得到一樣的路徑
```ruby
Rails.application.routes.draw do
    resources :cats do
    resources :dogs,shallow: true
  end
end
```
![](https://i.imgur.com/gxgCNUP.png)


---
### scope
namespace的路徑名比較嚴格無法用變數，當路徑想要用變數的時候可以用scope

```ruby
Rails.application.routes.draw do
  scope :cats do
    resources :dogs
  end
end  
```
scope的路徑名可以用字串，不會只能用符號
```ruby
Rails.application.routes.draw do
  scope "cats" do
    resources :dogs
  end
end  
```
寫上module可以增加controller的上一層資料表，不過不知道哪裡會用的上就是了。
```ruby
Rails.application.routes.draw do
  scope "cats",module: "animal" do
    resources :dogs
  end
end  
```
![](https://i.imgur.com/nqgPQsm.png)

```ruby
Rails.application.routes.draw do
  scope "@:cats" do
    resources :dogs
  end
end  
```
![](https://i.imgur.com/gOAlJJF.png)
透過字串的寫法，我們能在scope的路徑寫上變數