Tulee muistaa, että Rails on mielipidekehys ja yksi sen perusperiaatteista on konfiguroinnin sijasta sopiminen. Tämä tarkoittaa sitä, että ellei sinulla ole erittäin hyvää syytä, sinun ei pitäisi rikkoa mitään edellä mainituista malleista ja nimeämiskäytännöistä.
Jos esimerkiksi päättäisin koodata index-toiminnon muotoon get 'cars/index'
tai create-toiminnon muotoon post 'car/create'
, tämä rikkoisi Railsin out-of-the-box-käyttäytymisen apumetodeille, kuten form_for, link_to ja redirect_to.
Konventioiden rikkomisesta ilman tarkoitusta seuraa kaaos, ja siitä syntyy sotkuinen sotku, joka saa sinut taistelemaan kehystä vastaan tuntikausia.
Singulaaristen resurssien reitit
Mahdollista on myös reitit singulaarisille resursseille, eli resursseja, joita voidaan hakea ilman :id
:n määrittelyä, kuten current_user
:lle tai current_account
:lle sovellettavat reitit. Tämä voidaan toteuttaa käyttämällä Railsin sisäänrakennettuja singulaarisia resursseja.
resource :profile
Sisäkkäiset reitit
Joskus on tarpeen sijoittaa resursseja toisten resurssien sisään. Jos esimerkiksi haluan luoda varauksen tietylle autotallissani olevalle autolle, voi olla kätevämpää napata kyseisen auton :id
URL-osoitteesta kuin lomakkeen piilotetusta kentästä, jota pahantahtoinen käyttäjä voisi peukaloida. Tapa, jolla luomme sisäkkäisiä resursseja railsissa, on seuraava:
resources :cars do
resources :bookings
end
Tämä luo kaikki seitsemän CRUD-toimintoa autoihin sisäkkäin sijoitetuille varauksille. Yleensä et kuitenkaan tarvitse kaikkia seitsemää reittiä. Ja vaikka tarvitsisitkin, kaikkia niistä ei varmasti tarvitse sijoittaa toisiinsa. Oletetaan, että tarvitsemme toiminnon varauksen luomiseen (oletamme, että varauksen luomiseen tarkoitettu lomake on auton show-toiminnossa) ja olemassa olevan varauksen muokkaamiseen ja päivittämiseen. Pitääkö minun tietää auton :id
, jotta voin muokata/päivittää varausta? Vastaus on luonnollisesti ei. Siksi haluan, että sovellukseni vastaa seuraaviin URL-osoitteisiin:
# to CREATE a booking
POST request to http://my-ruby-garage.com/cars/:id/bookings/create# to EDIT a booking
GET request to http://my-ruby-garage.com/bookings/:id/edit# to UPDATE a booking
PATCH request to http://my-ruby-garage.com/bookings/:id/
Jotka generoidaan seuraavalla koodilla:
resources :cars do
resources :bookings, only:
end
resources :bookings, only:
Rails antaa meidän muuttaa sitä, mitkä vakiomuotoisista CRUD-reiteistä generoidaan, antamalla symbolijoukko tai yksittäinen symboli vaihtoehtoon :only
tai sen vastakohtaan :except
.
Muut kuin CRUD-reitit
Emme ole rajoitettuja seitsemään CRUD-resurssireittiin. Voimme myös määritellä reittejä, jotka koskevat yhtä resurssia (jäsenreitit) tai useita resursseja (kokoelmareitit).
Jäsenreitit
Jatkamalla RubyGarage-esimerkkiämme, autot voidaan pysäköidä autotalliin tai poistaa sieltä. Kuvitellaan, että meillä on ohjaimen toimintoja, jotka pystyvät suorittamaan näitä toimintoja, jotka muuttavat tietyn auton jotakin attribuuttia.
resources :cars do
member do
patch :park
patch :remove
end
end
Yllä olevan avulla voimme lähettää korjauspyynnöt osoitteisiin http://my-ruby-garage.com/cars/:id/park
ja http://my-ruby-garage.com/cars/:id/remove
ja etsiä tietyn auton ohjaimesta ennen resurssin muuttamista sen mukaisesti.
Kokoelmareitit
Samoin toisinaan halutaan suorittaa jokin toiminto useisiin resursseihin samanaikaisesti. Esimerkiksi ehkä meidän täytyy pysäköidä ja poistaa kerralla kokoelma autoja. Voimme käyttää seuraavaa koodia:
resources :cars do
collection do
post :park, as: :bulk_park
post :remove, as: :bulk_remove
end
end
Tässä asetamme sovelluksemme vastaamaan http://my-ruby-garage.com/cars/park
ja http://my-ruby-garage.com/cars/remove
ja vastaavasti nimeämme nämä toiminnot bulk_park ja bulk_remove. Muista, että voimme käyttää nimettyjä polkuja URL-polkujen luomiseen sovelluksemme sisällä. Rakentaaksemme polkuyhteyden pysäköidäksemme kokoelman autoja, voisimme käyttää:
<%= link_to "Park Cars", bulk_park_path, method: :post, class: "button" %>
Nimenomaiset reitit
Nimenomaiset reitit edeltää nimiavaruuslohkon sisällä olevien resurssien URL-polkua ja yrittää paikantaa asiaankuuluvat ohjaimet sellaisen moduulin alta, jolla on sama nimi kuin nimiavaruudella. Tyypillisiä käyttökohteita tälle kuviolle ovat admin-nimiavaruudet ja api-nimiavaruudet.
namespace :factory do
resources :cars
end
Tämä esimerkki rakentaa seuraavat reitit:
Prefix Verb URI Pattern Controller#Action factory_cars GET /factory/cars(.:format) factory/cars#index
POST /factory/cars(.:format) factory/cars#create factory_car GET /factory/cars/:id(.:format) factory/cars#show
PATCH /factory/cars/:id(.:format) factory/cars#update
PUT /factory/cars/:id(.:format) factory/cars#update
DELETE /factory/cars/:id(.:format) factory/cars#destroy
Ja myös kontrollerin pitäisi olla namespaced :
class Factory::CarsController < ApplicationController
# ...
end
Scoped Routes
Menetelmän scope
avulla voimme pysyä DRY:nä ja yhdistää toisiinsa liittyvät reitityssäännöt. Kun sitä käytetään ilman optioita, se on samanlainen kuin namespace
, mutta asiaankuuluvien ohjainten ei tarvitse olla moduulin nimitilassa.
scope :factory do
resources :cars
end
Generoi seuraavat reitit:
Prefix Verb URI Pattern Controller#Action factory_cars GET /factory/cars(.:format) cars#index
POST /factory/cars(.:format) cars#create factory_car GET /factory/cars/:id(.:format) cars#show
PATCH /factory/cars/:id(.:format) cars#update
PUT /factory/cars/:id(.:format) cars#update
DELETE /factory/cars/:id(.:format) cars#destroy
Scope tukee kolmea optiota: moduuli, polku ja as.
Esitettäköön, että meillä on monivaiheinen ohjattu ohjattu toiminto, jonka avulla luodaan uusi auto tehtaalle ja jota käsittelee ohjain, joka asuu ohjattujen ohjainten moduulissa. Haluamme, että polku näkyy selaimessa muodossa http://my-ruby-garage.com/create-a-car
ja että voimme viitata tähän reittiin sovelluksemme sisällä muodossa create_car
. On olemassa moduuli Wizard::Car
, joka tuntee ohjatun toiminnon jokaisen vaiheen.
scope module: 'wizards', path: 'create-a-car', as: 'create_car' do
Wizard::Car::STEPS.each do |step|
get step, to: "cars##{step}"
end
post :validate-step, to: 'cars#validate_step'
end
Yllä oleva koodi luo saman kuvion jokaiselle vaiheelle. Esimerkiksi askel1 on saatavilla selaimessa URL-osoitteen http://my-ruby-garage.com/create-a-car/step1
kautta, sitä vastaava lomake lähettää post-pyynnön osoitteeseen http://my-ruby-garage.com/create-a-car/validate-step
, ja polku voidaan kutsua kutsumalla create_car_step1_path
.
Reitin uudelleenohjaukset
Rails antaa meidän myös tehdä uudelleenohjauksia suoraan routes.rb
:ssa. Edellisessä esimerkissä haluan ehkä, että kaikki, jotka laskeutuvat kohtaan http://my-ruby-garage.com/create-a-car
, ohjataan automaattisesti ensimmäiseen vaiheeseen. Tämä voidaan toteuttaa seuraavalla koodilla:
get 'create-a-car',
to: redirect("/create-a-car/#{Wizard::SpotAccount::STEPS.first}")
Reitin oletusarvot
Voidaan määritellä oletusarvoparametreja reitissä välittämällä :defaults
-vaihtoehdolle hash.
resources :cars do
collection do
get :export, defaults: { format: 'csv' }
end
end
Käymällä tällä tavalla vieraileva http://my-ruby-garage.com/cars/export
kutsuu autojen ohjaimessa olevaa export-toimintoa ja vastaava ohjaimen toiminto vastaa oletusarvoisesti csv:llä.
Route Globbing
Käyttämällä jokerimerkkisegmenttejä (fragmentteja, joiden etuliitteenä on tähti) voimme määrittää, että reitin loput osat on sovitettava tiettyyn parametriin. Tätä kutsutaan route globbingiksi.
get '/rent/*slugs', to: 'cars#index', as: :rent_cars
Tämä reitti vastaisi http://my-ruby-garage.com/rent/lisbon/suv-sedan
ja asettaisi parametriksi ”lisbon/suv-sedan”. Tätä voitaisiin sitten käyttää haku- tai suodatusjärjestelmässä tietokantaamme vastaan löytääkseen Lissabonissa olevia autoja, jotka ovat tyyppiä suv tai sedan.
Kirjoitan gem Slugcatcheria tätä toiminnallisuutta silmällä pitäen, jotta voidaan merkitä Railsin mallit, joita voidaan hakea reitin sluggina.