โดย นางสาวแสงเดือน จันทร์ใหม่ – 16 ก.ค. 2558
Routing for Resources
Routing หรือการกำหนด route ให้ resources สำหรับ rails นั้นทำได้ง่ายๆ โดยการกำหนดค่าที่ไฟล์ routes.rb ในแอพพลิเคชั่น
ซึ่งใน rails จะทำทำการ maps ระหว่าง HTTP เมธอด กับ action ของ controller ตาม route ที่เรากำหนด
เราสามารถกำหนด route ได้ดังนี้
[code language="ruby"]
resources :recipes
[/code]
โดยค่า default ของ rails เมื่อประกาศ route ดังตัวอย่าง จะทำการ maps กับ method ของ controller 7 methods ด้วยกัน คือ show, index, new, create, edit, update, และ destroy ซึ่งเราสามารถเรียกใช้งานผ่าน HTTP method และ path เพื่อทำงานที่ action ต่างๆ ของ controller ได้ดังนี้
HTTP method | path | Controller action |
---|---|---|
GET | /recipes/:id | recipes#show |
GET | /recipes | recipes#index |
GET | /recipes/new | recipes#new |
POST | /recipes | recipes#create |
GET | /recipes/:id/edit | recipes#edit |
PUT/PATCH | /recipes/:id | recipes#update |
DELETE | /recipes/:id | recipes#destroy |
หากผู้ใช้ไม่ต้องการใช้ method ทั้งหมดตามค่า default ก็สามารถกำหนดได้ว่าต้องการ method อะไรบ้าง หรือไม่ต้องการ method อะไรบ้าง เช่น
[code language="ruby"]
resources :recipes, only: [:show, :index]
[/code]
เพื่อบอกกำหนดว่า recipes สามารถเข้าถึงได้เฉพาะ method show และ index
[code language="ruby"]
resources :recipes, except: [:destroy]
[/code]
เพื่อบอกกำหนดว่า recipes ไม่สามารถเข้าถึง method destroy ได้
นอกจากนี้เรายังสามารถกำหนด route ให้หลายๆ resource พร้อมกันได้
[code language="ruby"]
resources :recipes, :restaurants, :customers
[/code]
Singular Resources
เนื่องจาก Rails เป็นภาษา programming ที่ออกแแบบมาให้อ่านเข้าใจง่าย จึงให้ความสำคัญกับความหมายของคำ โดยเฉพาะคำพหูพจน์และคำเอกพจน์ สำหรับการกำหนด routing ถือว่าสำคัญมาก ซึ่งคำทีมีความหมายเดียวกันแต่เป็นพหูพจน์เมื่อนำมากำหนด route จะได้ดังตัวอย่างก่อนหน้าที่อธิบายไป แต่เมื่อคำความหมายเดิมในรูปเอกพจน์ ใช้กำหนด route จะได้ผลลัพธ์อีกแบบหนึ่งเรียกว่า singular resources
โดยการทำงานจะเหมือนกับการกำหนด route ให้ resources ปกติ มีการ maps ระหว่าง HTTP method และ Controller method เช่นเดียวกัน ที่ต่างกันคือ ค่า default เริ่มต้น จากปกติที่ default เริ่มต้นมี 7 methods แต่ singular จะเหลือ 6 methods ซึ่งจะตัด index ทิ้งไป ตัวอย่างการกำหนด route แบบ singular
[code language="ruby"]
resource :person
[/code]
ซึ่งสามารถเรียกใช้งาน HTTP method และ path เพื่อทำงานที่ action ต่างๆ ของ controller ได้ดังนี้
HTTP method | path | Controller action |
---|---|---|
GET | /person | persons#show |
GET | /person/new | persons#new |
POST | /person | persons#create |
GET | /person/edit | persons#edit |
PUT/PATCH | /person | persons#update |
DELETE | /person | persons#destroy |
Nested Resources
Nested Resources เป็นการกำหนด resources ที่อยู่ภายใต้อีก resources หนึ่ง หรือเป็นการกำหนด resources ที่มีความสัมพันธ์ในลักษณะ แม่-ลูก กัน เช่น
[code language="ruby"]
resources :recipes do
resources :ingredients
end
[/code]
โดยเมื่อต้องการเข้าถึงการใช้งาน method ต่างๆ ใน ingredients สามารถทำได้ดังนี้
HTTP method | path | Controller action |
---|---|---|
GET | /recipes/:recipe_id/ingredients/:id | ingredients#show |
GET | /recipes/:recipe_id/ingredients | ingredients#index |
GET | /recipes/:recipe_id/ingredients/new | ingredients#new |
POST | /recipes/:recipe_id/ingredients | ingredients#create |
GET | /recipes/:recipe_id/ingredients/:id/edit | ingredients#edit |
PUT/PATCH | /recipes/:recipe_id/ingredients/:id | ingredients#update |
DELETE | /recipes/:recipe_id/ingredients/:id | ingredients#destroy |
สิ่งสำคัญที่ต้องพิจารณาเมื่อใช้ Nested Resources คือ ความลึกของความสัมพันธ์ที่จะกำหนด เนื่องจาก rails ไม่ได้จำกัดขนาดความลึกของความสัมพันธ์ แต่ความสัมพันธ์ยิ่งลึก Url จะยิ่งยาว ซึ่งความยาวของ Url มีขีดจำกัด ดังนั้น เมื่อต้องใช้ Nested Resources จึงต้องพิจารณาส่วนนี้ให้ดี
การเพิ่ม path เพิ่มเติมจาก RESTful route
แม้ routing ของ rails จะมี default method ที่ครบถ้วนตามการใช้งานพื้นฐานแล้วก็ตาม แต่บ่อยครั้งที่เราจำเป็นต้องสร้าง method เพิ่มเติมเพื่อการทำงานที่ซับซ้อนยิ่งขึ้น จึงต้องมีการกำหนด route เพิ่มเติมให้ resources
โดยลักษณะของ method สำหรับเข้าถึง resources มีลักษณะสำคัญ 2 ประการคือ route ที่ต้องการ id เพื่อเข้าถึง resources และ route ที่ไม่ต้องมี id ก็สามารถเข้าถึง resources ได้
ดังนั้นการเพิ่ม route ที่เหมาะสมจึงทำได้สองวิธี ดังนี้
[code language="ruby"]
resources :products do
member do
get price
end
end
[/code]
member ใช้สำหรับเข้าถึง resources ที่ต้องใช้ id
จากตัวอย่าง สามารถเรียกใช้งานได้ดังนี้
HTTP method | path | Controller action |
---|---|---|
GET | /products/:id/price | products#price |
[code language="ruby"]
resources :products do
collection do
get my_products
end
end
[/code]
collection ใช้สำหรับเข้าถึง resources โดยไม่ต้องระบุ id
จากตัวอย่าง สามารถเรียกใช้งานได้ดังนี้
HTTP method | path | Controller action |
---|---|---|
GET | /products/my_products | products#my_products |
ซึ่งทั้งหมดนี้เป็นเพียงการใช้งานพื้นฐานอย่างง่าย โดยสามารถศึกษาการใช้งานเพิ่มเติม เพื่องานที่ซับซ้อนมากยิ่งขึ้นได้ที่