1 Apžvalga: kaip dalių suderinamumas
Šiame vadove dėmesys skiriamas valdiklio ir peržiūros sąveikai modelio-peržiūros-valdiklio trikampyje. Kaip žinote, valdiklis atsakingas už viso proceso, susijusio su užklausos tvarkymu „Rails“, orkestravimą, nors paprastai jis perduoda bet kokį sunkų kodą modeliui. Tačiau, kai ateina laikas atsiųsti atsaką vartotojui, valdiklis perduoda reikalus peržiūrai. Šiame vadove nagrinėjamas būtent šis perduodimas.
Iš esmės tai apima sprendimą, ką siųsti kaip atsaką ir kvietimą tinkamai metodui, kuris sukurtų tą atsaką. Jei atsakas yra visiškai išplėstas peržiūros langas, „Rails“ taip pat atlieka papildomą darbą, kad apgaubtų peržiūrą maketu ir galbūt įtrauktų dalinius peržiūras. Vėliau šiame vadove pamatysite visas šias kelias.
2 Atsakų kūrimas
Iš valdiklio perspektyvos yra trys būdai sukurti HTTP atsaką:
- Iškviesti
render
, kad sukurtumėte visą atsaką, kurį siųsti naršyklei - Iškviesti
redirect_to
norint siųsti naršyklei HTTP peradresavimo būsenos kodą - Iškviesti
head
norint sukurti atsaką, kuris sudarytas tik iš HTTP antraščių, kurias siųsti naršyklei
2.1 Numatytasis atvaizdavimas: konvencija virš konfigūracijos veikimo
Esate girdėję, kad „Rails“ skatina „konvenciją virš konfigūracijos“. Numatytasis atvaizdavimas yra puikus šios taisyklės pavyzdys. Pagal numatymą „Rails“ valdikliai automatiškai atvaizduoja peržiūras, kurių pavadinimai atitinka galiojančius maršrutus. Pavyzdžiui, jei jūsų BooksController
klasėje yra šis kodas:
class BooksController < ApplicationController
end
Ir šis jūsų maršrutų failas:
resources :books
Ir turite peržiūros failą app/views/books/index.html.erb
:
<h1>Knygos greitai bus!</h1>
„Rails“ automatiškai atvaizduos app/views/books/index.html.erb
, kai naršysite adresu /books
, ir ekrane matysite „Knygos greitai bus!“.
Tačiau ateinančios peržiūros langas yra tik minimaliai naudingas, todėl greitai sukursite savo Book
modelį ir pridėsite indekso veiksmą prie BooksController
:
class BooksController < ApplicationController
def index
@books = Book.all
end
end
Atkreipkite dėmesį, kad indekso veiksmo pabaigoje neturime aiškaus atvaizdavimo, vadovaujantis „konvencija virš konfigūracijos“ principu. Taisyklė yra tokia, jei veiksmo pabaigoje iš esmės nieko neatskleidžiate, „Rails“ automatiškai ieškos action_name.html.erb
šablono valdiklio peržiūros kelyje ir jį atvaizduos. Taigi šiuo atveju „Rails“ atvaizduos app/views/books/index.html.erb
failą.
Jei norime peržiūroje rodyti visų knygų savybes, tai galime padaryti naudodami ERB šabloną, panašų į šį:
<h1>Knygų sąrašas</h1>
<table>
<thead>
<tr>
<th>Pavadinimas</th>
<th>Turinys</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% @books.each do |book| %>
<tr>
<td><%= book.title %></td>
<td><%= book.content %></td>
<td><%= link_to "Rodyti", book %></td>
<td><%= link_to "Redaguoti", edit_book_path(book) %></td>
<td><%= link_to "Naikinti", book, data: { turbo_method: :delete, turbo_confirm: "Ar tikrai?" } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to "Nauja knyga", new_book_path %>
PASTABA: Tikras atvaizdavimas atliekamas naudojant modulio ActionView::Template::Handlers
įdėtus klases. Šiame vadove nėra nagrinėjamas šis procesas, tačiau svarbu žinoti, kad jūsų peržiūros failo plėtinys kontroliuoja šablono tvarkyklės pasirinkimą.
2.2 Naudodami render
Dažniausiai valdiklio render
metodas atlieka pagrindinį darbą, atvaizduodamas jūsų programos turinį naršyklės naudojimui. Yra įvairių būdų pritaikyti render
veikimą. Galite atvaizduoti numatytąją peržiūrą „Rails“ šablonui arba konkretų šabloną, arba failą, arba įterptą kodą, arba visai nieko. Galite atvaizduoti tekstą, JSON ar XML. Taip pat galite nurodyti atvaizduojamo atsakymo turinio tipą arba HTTP būsenos kodą.
PATARIMAS: Jei norite pamatyti tikslų render
iškvietimo rezultatą, nereikalaudami jo tikrinti naršyklėje, galite iškviesti render_to_string
. Šis metodas priima tiksliai tuos pačius parametrus kaip ir render
, bet grąžina eilutę, o ne siunčia atsaką atgal į naršyklę.
2.2.1 Vaizdo atvaizdavimas veiksmo
Jei norite atvaizduoti vaizdą, kuris atitinka kitą šablono šablono toje pačioje kontroleryje, galite naudoti render
su vaizdo pavadinimu:
def update
@book = Book.find(params[:id])
if @book.update(book_params)
redirect_to(@book)
else
render "edit"
end
end
Jei update
iškvietimas nepavyksta, šio kontrolerio update
veiksmas atvaizduos edit.html.erb
šabloną, priklausančią tam pačiam kontroleriui.
Jei norite, galite naudoti simbolį vietoj eilutės, kad nurodytumėte veiksmą, kurį norite atvaizduoti:
def update
@book = Book.find(params[:id])
if @book.update(book_params)
redirect_to(@book)
else
render :edit, status: :unprocessable_entity
end
end
2.2.2 Vaizdo atvaizdavimas iš kito kontrolerio veiksmo
Ką daryti, jei norite atvaizduoti šablono iš visiškai skirtingo kontrolerio nei tas, kuriame yra veiksmo kodas? Tai taip pat galite padaryti su render
, kuris priima visą kelią (atitinkamai app/views
) šablono atvaizdavimui. Pavyzdžiui, jei vykdote kodą AdminProductsController
, kuris yra app/controllers/admin
, galite atvaizduoti veiksmo rezultatus šablonui app/views/products
šiuo būdu:
render "products/show"
Rails žino, kad šis vaizdas priklauso kitam kontroleriui dėl įterpto pasvirimo ženklo eilutėje. Jei norite būti aiškesni, galite naudoti :template
parinktį (kuri buvo privaloma Rails 2.2 ir ankstesnėse versijose):
render template: "products/show"
2.2.3 Apvyniojimas
Aukščiau aprašyti du būdai atvaizduoti (atvaizduoti kito veiksmo šabloną tame pačiame kontroleryje ir atvaizduoti kito veiksmo šabloną kitame kontroleryje) iš tikrųjų yra tų pačių operacijų variantai.
Iš tikrųjų, BooksController
klasėje, update
veiksme, kai norime atvaizduoti redagavimo šabloną, jei knyga nesėkmingai atnaujinama, visi šie render
iškvietimai atvaizduos edit.html.erb
šabloną views/books
kataloge:
render :edit
render action: :edit
render "edit"
render action: "edit"
render "books/edit"
render template: "books/edit"
Kurį naudoti, tai tik stiliaus ir konvencijos klausimas, bet taisyklė yra naudoti paprasčiausią, bet prasmingiausią kodui, kurį rašote.
2.2.4 Naudodami render
su :inline
Render
metodas gali visiškai atsisakyti vaizdo, jei norite naudoti :inline
parinktį, kad dalį ERB pateiktumėte kaip metodo iškvietimo dalį. Tai yra visiškai teisinga:
render inline: "<% products.each do |p| %><p><%= p.name %></p><% end %>"
ĮSPĖJIMAS: Yra labai mažai geros priežasties naudoti šią parinktį. ERB maišymas į jūsų kontrolerius pažeidžia Rails MVC orientaciją ir padarys sunkiau kitoms programuotojams sekti jūsų projekto logiką. Vietoj to naudokite atskirą erb vaizdą.
Pagal numatytuosius nustatymus, įterpimo atvaizdavimas naudoja ERB. Galite priversti jį naudoti Builder su :type
parinktimi:
render inline: "xml.p {'Horrid coding practice!'}", type: :builder
2.2.5 Teksto atvaizdavimas
Galite siųsti gryną tekstą - be jokio žymėjimo - atgal į naršyklę, naudodami :plain
parinktį render
:
render plain: "OK"
PATARIMAS: Grynasis tekstas yra naudingiausias, kai reaguojate į Ajax arba interneto paslaugų užklausas, kurios tikisi kažko kito nei tinkamas HTML.
Pastaba: Pagal numatytuosius nustatymus, jei naudojate :plain
parinktį, tekstas atvaizduojamas be naudojant esamą išdėstymą. Jei norite, kad „Rails“ įdėtų tekstą į esamą išdėstymą, turite pridėti layout: true
parinktį ir naudoti .text.erb
plėtinį išdėstymo failui.
2.2.6 HTML atvaizdavimas
Galite siųsti HTML eilutę atgal į naršyklę, naudodami :html
parinktį render
:
render html: helpers.tag.strong('Not Found')
PATARIMAS: Tai naudinga, kai atvaizduojate mažą HTML kodo fragmentą. Tačiau jei žymėjimas yra sudėtingas, galbūt norėsite jį perkelti į šablonų failą.
Pastaba: Naudodami html:
parinktį, jei eilutė nėra sudaryta iš html_safe
-sąmoningų API, HTML entitetai bus pakeisti.
2.2.7 JSON atvaizdavimas
JSON yra „JavaScript“ duomenų formatas, kurį naudoja daugelis „Ajax“ bibliotekų. „Rails“ turi įdiegtą palaikymą, skirtą objektų konvertavimui į JSON ir šio JSON atvaizdavimui naršyklėje:
render json: @product
PATARIMAS: Jums nereikia iškviesti to_json
objekte, kurį norite atvaizduoti. Jei naudojate :json
parinktį, render
automatiškai iškvies to_json
už jus.
2.2.8 XML atvaizdavimas
Rails taip pat turi įdiegtą palaikymą objektų konvertavimui į XML ir šio XML atvaizdavimui grąžinant skambinančiajai pusei:
render xml: @product
PATARIMAS: Jums nereikia iškviesti to_xml
metodo objekte, kurį norite atvaizduoti. Jei naudojate :xml
parinktį, render
automatiškai iškvies to_xml
už jus.
2.2.9 Paprasto JavaScript atvaizdavimas
Rails gali atvaizduoti paprastą JavaScript:
render js: "alert('Sveiki, Rails');"
Tai siųs pateiktą eilutę naršyklei su text/javascript
MIME tipu.
2.2.10 Neapdoroto turinio atvaizdavimas
Galite siųsti neapdorotą turinį naršyklei, nustatydami :body
parinktį render
metode, be nustatant jokio turinio tipo:
render body: "neapdorotas"
PATARIMAS: Šią parinktį turėtumėte naudoti tik tada, jei jums nerūpi atsakymo turinio tipas. Daugumai atvejų būtų tinkamesnis :plain
arba :html
.
PASTABA: Jei neperrašote, jūsų atsakymas, grąžintas naudojant šią atvaizdavimo parinktį, bus text/plain
, nes tai yra numatytasis turinio tipas veiksmo perdavimo atveju.
2.2.11 Neapdoroto failo atvaizdavimas
Rails gali atvaizduoti neapdorotą failą iš absoliučios kelio. Tai naudinga sąlygiškai atvaizduoti statinius failus, pvz., klaidų puslapius.
render file: "#{Rails.root}/public/404.html", layout: false
Tai atvaizduoja neapdorotą failą (jis nepalaiko ERB ar kitų apdorojimo priemonių). Pagal numatytuosius nustatymus jis atvaizduojamas esamoje išdėstyme.
ĮSPĖJIMAS: Naudodami :file
parinktį kartu su naudotojo įvestimi, gali kilti saugumo problemų, nes puolėjas galėtų naudoti šį veiksmą, norėdamas pasiekti jūsų failų sistemoje esančius saugumo jautrius failus.
PATARIMAS: send_file
dažnai yra greitesnė ir geresnė parinktis, jei nereikia išdėstymo.
2.2.12 Objektų atvaizdavimas
Rails gali atvaizduoti objektus, kurie atsako į :render_in
metodą.
render MyRenderable.new
Tai iškviečia render_in
metodą pateiktame objekte su esamu rodinio kontekstu.
Taip pat galite pateikti objektą naudodami :renderable
parinktį render
metode:
render renderable: MyRenderable.new
2.2.13 Parinktys render
metode
Kviečiant render
metodą, paprastai priimamos šešios parinktys:
:content_type
:layout
:location
:status
:formats
:variants
2.2.13.1 :content_type
parinktis
Pagal numatytuosius nustatymus, Rails aptarnaus atvaizdavimo operacijos rezultatus su MIME turinio tipu text/html
(arba application/json
, jei naudojate :json
parinktį, arba application/xml
naudojant :xml
parinktį). Yra atvejų, kai norėtumėte tai pakeisti, ir tai galite padaryti nustatydami :content_type
parinktį:
render template: "feed", content_type: "application/rss"
2.2.13.2 :layout
parinktis
Su dauguma render
parinkčių, atvaizduotas turinys rodomas kaip esamo išdėstymo dalis. Apie išdėstymus ir kaip juos naudoti sužinosite vėliau šiame vadove.
Galite naudoti :layout
parinktį, kad Rails naudotų konkretų failą kaip esamo veiksmo išdėstymą:
render layout: "special_layout"
Taip pat galite pasakyti Rails, kad atvaizduotų be jokio išdėstymo:
render layout: false
2.2.13.3 :location
parinktis
Galite naudoti :location
parinktį, kad nustatytumėte HTTP Location
antraštę:
render xml: photo, location: photo_url(photo)
2.2.13.4 :status
parinktis
Rails automatiškai sugeneruos atsakymą su teisingu HTTP būsenos kodu (daugumoje atvejų tai yra 200 OK
). Galite naudoti :status
parinktį, kad tai pakeistumėte:
render status: 500
render status: :forbidden
Rails supranta tiek skaitinius būsenos kodus, tiek žemiau pateiktus simbolius.
Atsakymo klasė | HTTP būsenos kodas | Simbolis |
---|---|---|
Informacinis | 100 | :continue |
101 | :switching_protocols | |
102 | :processing | |
Sėkmė | 200 | :ok |
201 | :created | |
202 | :accepted | |
203 | :non_authoritative_information | |
204 | :no_content | |
205 | :reset_content | |
206 | :partial_content | |
207 | :multi_status | |
208 | :already_reported | |
226 | :im_used | |
Nukreipimas | 300 | :multiple_choices |
301 | :moved_permanently | |
302 | :found | |
303 | :see_other | |
304 | :not_modified | |
305 | :use_proxy | |
307 | :temporary_redirect | |
308 | :permanent_redirect | |
Kliento klaida | 400 | :bad_request |
401 | :unauthorized | |
402 | :payment_required | |
403 | :forbidden | |
404 | :not_found | |
405 | :method_not_allowed | |
406 | :not_acceptable | |
407 | :proxy_authentication_required | |
408 | :request_timeout | |
409 | :conflict | |
410 | :gone | |
411 | :length_required | |
412 | :precondition_failed | |
413 | :payload_too_large | |
414 | :uri_too_long | |
415 | :unsupported_media_type | |
416 | :range_not_satisfiable | |
417 | :expectation_failed | |
421 | :misdirected_request | |
422 | :unprocessable_entity | |
423 | :locked | |
424 | :failed_dependency | |
426 | :upgrade_required | |
428 | :precondition_required | |
429 | :too_many_requests | |
431 | :request_header_fields_too_large | |
451 | :unavailable_for_legal_reasons | |
Serverio klaida | 500 | :internal_server_error |
501 | :not_implemented | |
502 | :bad_gateway | |
503 | :service_unavailable | |
504 | :gateway_timeout | |
505 | :http_version_not_supported | |
506 | :variant_also_negotiates | |
507 | :insufficient_storage | |
508 | :loop_detected | |
510 | :not_extended | |
511 | :network_authentication_required |
PASTABA: Jei bandysite atvaizduoti turinį kartu su ne-turinio būsenos kodu (100-199, 204, 205 arba 304), jis bus pašalintas iš atsakymo.
2.2.13.5 :formats
parinktis
Rails naudoja formą, nurodytą užklausoje (arba :html
pagal numatytuosius nustatymus). Galite tai pakeisti, perduodant :formats
parinktį su simboliu arba masyvu:
render formats: :xml
render formats: [:json, :xml]
Jei šablonas su nurodytu formatu neegzistuoja, iškeliama klaida ActionView::MissingTemplate
.
2.2.13.6 :variants
parinktis
Tai nurodo Rails ieškoti šablono variantų to paties formato. Galite nurodyti variantų sąrašą, perduodant :variants
parinktį su simboliu arba masyvu.
Pavyzdys:
# iškviesta HomeController#index
render variants: [:mobile, :desktop]
Su šiais variantais Rails ieškos šių šablonų rinkinio ir naudos pirmąjį, kuris egzistuoja.
app/views/home/index.html+mobile.erb
app/views/home/index.html+desktop.erb
app/views/home/index.html.erb
Jei šablonas su nurodytu formatu neegzistuoja, iškeliama klaida ActionView::MissingTemplate
.
Vietoje varianto nustatymo renderinimo metu, jį taip pat galite nustatyti užklausos objekte savo valdiklio veiksmo metu.
def index
request.variant = determine_variant
end
private
def determine_variant
variant = nil
# kodas, kuris nustato naudotinus variantus
variant = :mobile if session[:use_mobile]
variant
end
2.2.14 Ieškant išdėstymo
Norėdami rasti dabartinį išdėstymą, Rails pirmiausia ieško failo app/views/layouts
, kurio bazinis pavadinimas yra toks pat kaip ir valdiklio. Pavyzdžiui, atvaizduojant veiksmus iš PhotosController
klasės, bus naudojamas app/views/layouts/photos.html.erb
(arba app/views/layouts/photos.builder
). Jei nėra tokio valdiklio specifinio išdėstymo, Rails naudos app/views/layouts/application.html.erb
arba app/views/layouts/application.builder
. Jei nėra .erb
išdėstymo, Rails naudos .builder
išdėstymą, jei toks egzistuoja. Rails taip pat suteikia keletą būdų tiksliau priskirti konkretų išdėstymą atskiriems valdikliams ir veiksmams.
2.2.14.1 Išdėstymo nustatymas valdikliams
Galite perrašyti numatytuosius išdėstymo konvencijas savo valdikliuose naudodami layout
deklaraciją. Pavyzdžiui:
class ProductsController < ApplicationController
layout "inventory"
#...
end
Su šia deklaracija, visi ProductsController
atvaizduojami rodiniai naudos app/views/layouts/inventory.html.erb
kaip savo išdėstymą.
Norėdami priskirti konkretų išdėstymą visai programai, naudokite layout
deklaraciją savo ApplicationController
klasėje:
class ApplicationController < ActionController::Base
layout "main"
#...
end
Su šia deklaracija, visi programos rodiniai naudos app/views/layouts/main.html.erb
kaip savo išdėstymą.
2.2.14.2 Išdėstymo pasirinkimas vykdymo metu
Galite naudoti simbolį, kad atidėtumėte išdėstymo pasirinkimą iki užklausos apdorojimo:
class ProductsController < ApplicationController
layout :products_layout
def show
@product = Product.find(params[:id])
end
private
def products_layout
@current_user.special? ? "special" : "products"
end
end
Dabar, jei dabartinis vartotojas yra specialus vartotojas, jis gaus specialų išdėstymą, peržiūrėdamas produktą.
Netgi galite naudoti įterptinį metodą, pvz., Proc
, kad nustatytumėte išdėstymą. Pavyzdžiui, jei perduodate Proc
objektą, blokas, kurį duodate Proc
, bus duotas controller
egzemplioriui, todėl išdėstymas gali būti nustatomas pagal dabartinę užklausą:
class ProductsController < ApplicationController
layout Proc.new { |controller| controller.request.xhr? ? "popup" : "application" }
end
2.2.14.3 Sąlyginiai išdėstymai
Valdiklio lygyje nurodyti išdėstymai palaiko :only
ir :except
parinktis. Šios parinktys priima metodų pavadinimą arba metodų pavadinimų masyvą, atitinkančių metodus valdiklyje:
class ProductsController < ApplicationController
layout "product", except: [:index, :rss]
end
Su šia deklaracija, product
išdėstymas bus naudojamas visiems, išskyrus rss
ir index
metodus.
2.2.14.4 Išdėstymo paveldėjimas
Išdėstymo deklaracijos kaskadinamos žemyn hierarchijoje, ir specifinės išdėstymo deklaracijos visada perrašo bendresnes. Pavyzdžiui:
application_controller.rb
class ApplicationController < ActionController::Base layout "main" end
articles_controller.rb
class ArticlesController < ApplicationController end
special_articles_controller.rb
class SpecialArticlesController < ArticlesController layout "special" end
old_articles_controller.rb
class OldArticlesController < SpecialArticlesController layout false def show @article = Article.find(params[:id]) end def index @old_articles = Article.older render layout: "old" end # ... end
Šioje programoje:
- Bendrai, rodiniai bus atvaizduojami pagal
main
išdėstymą ArticlesController#index
naudosmain
išdėstymąSpecialArticlesController#index
naudosspecial
išdėstymąOldArticlesController#show
nebus naudojamas joks išdėstymasOldArticlesController#index
naudosold
išdėstymą ##### Šablonų paveldėjimas
Panašiai kaip ir išdėstymo paveldėjimo logika, jei šablonas ar dalis nerandama konvenciniame kelyje, valdiklis ieškos šablono ar dalies, kurį reikia atvaizduoti, jo paveldėjimo grandinėje. Pavyzdžiui:
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
end
# app/controllers/admin_controller.rb
class AdminController < ApplicationController
end
# app/controllers/admin/products_controller.rb
class Admin::ProductsController < AdminController
def index
end
end
admin/products#index
veiksmo paieškos tvarka bus:
app/views/admin/products/
app/views/admin/
app/views/application/
Tai padaro app/views/application/
puikiu vietu bendriems daliniams, kurie gali būti atvaizduojami ERB kaip toks:
<%# app/views/admin/products/index.html.erb %>
<%= render @products || "empty_list" %>
<%# app/views/application/_empty_list.html.erb %>
Šiame sąraše nėra jokių elementų <em>dar</em>.
2.2.15 Dvigubo atvaizdavimo klaidų išvengimas
Anksčiau ar vėliau, dauguma „Rails“ programuotojų matys klaidos pranešimą „Vienu veiksmu galima atvaizduoti arba nukreipti tik kartą“. Nors tai gali būti erzinantis, tai relativiai lengva ištaisyti. Paprastai tai atsitinka dėl pagrindinio supratimo apie tai, kaip veikia render
funkcija.
Pavyzdžiui, šis kodas sukels klaidą:
def show
@book = Book.find(params[:id])
if @book.special?
render action: "special_show"
end
render action: "regular_show"
end
Jei @book.special?
įvertinimas yra true
, „Rails“ pradės atvaizdavimo procesą, kad įdėtų @book
kintamąjį į special_show
rodinį. Tačiau tai ne sustabdys likusio kodo vykdymo show
veiksme, ir kai „Rails“ pasieks veiksmo pabaigą, jis pradės atvaizduoti regular_show
rodinį - ir išmes klaidą. Sprendimas yra paprastas: įsitikinkite, kad vienoje kodo eigoje yra tik vienas render
arba redirect
kvietimas. Vienas dalykas, kuris gali padėti, yra return
. Štai patobulinta metodo versija:
def show
@book = Book.find(params[:id])
if @book.special?
render action: "special_show"
return
end
render action: "regular_show"
end
Atkreipkite dėmesį, kad neaiškus render
, atliekamas ActionController
, nustato, ar buvo iškviestas render
, todėl šis kodas veiks be klaidų:
def show
@book = Book.find(params[:id])
if @book.special?
render action: "special_show"
end
end
Tai atvaizduos knygą su nustatyta special?
reikšme naudojant special_show
šabloną, o kitos knygos bus atvaizduojamos naudojant numatytąjį show
šabloną.
2.3 Nukreipimas naudojant redirect_to
Kitas būdas tvarkyti grąžinimo atsakus į HTTP užklausą yra naudojant redirect_to
. Kaip matėte, render
nurodo „Rails“, kurį rodinį (ar kitą turinį) naudoti atsakui konstruoti. redirect_to
metodas daro visiškai kitą dalyką: jis praneša naršyklei, kad ji turi siųsti naują užklausą kitam URL. Pavyzdžiui, galite nukreipti iš bet kurio kodo vietos į jūsų programoje esančių nuotraukų indeksą šiuo kvietimu:
redirect_to photos_url
Galite naudoti redirect_back
, kad grąžintumėte vartotoją į puslapį, iš kurio jis tik ką atėjo. Ši vieta gaunama iš HTTP_REFERER
antraštės, kurią naršyklė ne visada nustato, todėl turite nurodyti fallback_location
, kurį naudoti šiuo atveju.
redirect_back(fallback_location: root_path)
PASTABA: redirect_to
ir redirect_back
nebaigia ir nedelsiai grąžina vykdymą iš metodo, bet tiesiog nustato HTTP atsakus. Po jų vykdomi teiginiai. Jei reikia, galite sustabdyti naudodami aiškų return
arba kitą stabdymo mechanizmą.
2.3.1 Skirtingas nukreipimo būsenos kodas
„Rails“ naudoja HTTP būsenos kodą 302, laikiną nukreipimą, kai iškviečiate redirect_to
. Jei norite naudoti kitą būsenos kodą, pvz., 301, nuolatinį nukreipimą, galite naudoti :status
parinktį:
redirect_to photos_path, status: 301
Kaip ir :status
parinktis render
funkcijai, :status
parinktis redirect_to
priima tiek skaitines, tiek simbolines antraštės žymėjimus.
2.3.2 Skirtumas tarp render
ir redirect_to
Kartais neįgudę programuotojai mano, kad redirect_to
yra rūšis goto
komandos, perkeliančios vykdymą iš vienos vietos į kitą jūsų „Rails“ kode. Tai neteisinga. Jūsų kodas sustoja ir laukia naujos užklausos iš naršyklės. Tiesiog atsitinka, kad jūs pasakėte naršyklei, kokią užklausą ji turėtų atlikti toliau, siųsdami atgal HTTP 302 būsenos kodą.
Norėdami pamatyti skirtumą, apsvarstykite šiuos veiksmus:
def index
@books = Book.all
end
def show
@book = Book.find_by(id: params[:id])
if @book.nil?
render action: "index"
end
end
Su šiuo kodu forma, tikriausiai atsiras problema, jei @book
kintamasis yra nil
. Atminkite, kad render :action
nevykdo jokio kodo tiksliniame veiksme, todėl niekas nesukonfigūruos @books
kintamojo, kurio tikriausiai reikės index
rodiniui. Vienas būdas tai ištaisyti yra nukreipti vietoj atvaizdavimo:
```ruby
def index
@books = Book.all
end
def show @book = Book.find_by(id: params[:id]) if @book.nil? redirect_to action: :index end end ```
Su šiuo kodu naršyklė atliks naują užklausą indekso puslapiui, vyks index
metodo kodas ir viskas bus gerai.
Vienintelis šio kodo trūkumas yra tai, kad jis reikalauja kelionės į naršyklę: naršyklė paprašė parodyti veiksmą su /books/1
ir valdiklis nustato, kad knygų nėra, todėl valdiklis išsiunčia 302 nukreipimo atsaką į naršyklę, nurodydamas jam eiti į /books/
, naršyklė tai padaro ir siunčia naują užklausą atgal į valdiklį, šį kartą jau prašydama index
veiksmo, valdiklis tada gauna visas knygas duomenų bazėje ir atvaizduoja indekso šabloną, siunčiant jį atgal į naršyklę, kuri jį rodo ekrane.
Nors mažame taikyme šis papildomas delsimas gali nebūti problema, tai verta apsvarstyti, jei reikia greito atsako laiko. Galime parodyti vieną būdą tai tvarkyti su sukonstruotu pavyzdžiu:
def index
@books = Book.all
end
def show
@book = Book.find_by(id: params[:id])
if @book.nil?
@books = Book.all
flash.now[:alert] = "Jūsų knyga nerasta"
render "index"
end
end
Tai aptiktų, kad nėra knygų su nurodytu ID, užpildytų @books
kintamąjį visomis knygomis modelyje ir tiesiogiai atvaizduotų index.html.erb
šabloną, grąžindamas jį naršyklei su informaciniu pranešimu, kuris pasakytų vartotojui, kas nutiko.
2.4 Naudodami head
norint sukurti tik antraštes
head
metodas gali būti naudojamas siųsti naršyklei tik antraštes turinčius atsakymus. head
metodas priima skaičių arba simbolį (žr. nuorodų lentelę), kuris nurodo HTTP būsenos kodą. Parametrai interpretuojami kaip antraščių pavadinimų ir reikšmių hainas. Pavyzdžiui, galite grąžinti tik klaidos antraštę:
head :bad_request
Tai sukurtų šią antraštę:
HTTP/1.1 400 Bad Request
Connection: close
Date: Sun, 24 Jan 2010 12:15:53 GMT
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8
X-Runtime: 0.013483
Set-Cookie: _blog_session=...snip...; path=/; HttpOnly
Cache-Control: no-cache
Arba galite naudoti kitas HTTP antraštes, kad perduotumėte kitą informaciją:
head :created, location: photo_path(@photo)
Kas sukurtų:
HTTP/1.1 201 Created
Connection: close
Date: Sun, 24 Jan 2010 12:16:44 GMT
Transfer-Encoding: chunked
Location: /photos/1
Content-Type: text/html; charset=utf-8
X-Runtime: 0.083496
Set-Cookie: _blog_session=...snip...; path=/; HttpOnly
Cache-Control: no-cache
3 Maketavimo išdėstymas
Kai „Rails“ atvaizduoja rodinį kaip atsaką, jis tai daro derindamas rodinį su esamu išdėstymu, naudodamas taisykles, kurios buvo aptartos anksčiau šiame vadove. Išdėstyme turite tris įrankius, skirtus sujungti skirtingus išvesties gabalus, kad sudarytumėte visą atsaką:
- Turtų žymos
yield
ircontent_for
- Daliniai
3.1 Turtų žymių pagalbininkai
Turtų žymių pagalbininkai teikia metodus, skirtus generuoti HTML, kuris susieja rodinius su kanalais, „JavaScript“, stiliaus lapais, vaizdais, vaizdo įrašais ir garso įrašais. „Rails“ yra šeši turtų žymių pagalbininkai:
Galite naudoti šias žymes išdėstyme ar kituose rodiniuose, nors auto_discovery_link_tag
, javascript_include_tag
ir stylesheet_link_tag
dažniausiai naudojami išdėstymo <head>
skyriuje.
ĮSPĖJIMAS: Turtų žymių pagalbininkai ne patikrina, ar turinys yra nurodytose vietose; jie tiesiog priima, kad žinote, ką darote, ir generuoja nuorodą.
3.1.1 Kanalų susiejimas su auto_discovery_link_tag
auto_discovery_link_tag
pagalbininkas sukuria HTML, kurį dauguma naršyklių ir kanalų skaitytuvų gali naudoti, kad aptiktų RSS, Atom ar JSON kanalų buvimą. Jis priima nuorodos tipo (:rss
, :atom
ar :json
), nuorodų generavimui perduodamų parinkčių hainą ir žymos parinkčių hainą:
<%= auto_discovery_link_tag(:rss, {action: "feed"},
{title: "RSS kanalas"}) %>
auto_discovery_link_tag
yra trys žymos parinktys:
:rel
nurodorel
reikšmę nuorodoje. Numatytoji reikšmė yra „alternate“.:type
nurodo aiškų MIME tipą. „Rails“ automatiškai sugeneruos tinkamą MIME tipą.:title
nurodo nuorodos pavadinimą. Numatytoji reikšmė yra didžiosiomis raidėmis rašytas:type
pavadinimas, pvz., „ATOM“ arba „RSS“. #### Susiejimas su JavaScript failais naudojantjavascript_include_tag
javascript_include_tag
pagalbininkas grąžina HTML script
žymą kiekvienam pateiktam šaltiniui.
Jei naudojate „Rails“ su įjungtu Asset Pipeline, šis pagalbininkas sugeneruos nuorodą į /assets/javascripts/
, o ne į public/javascripts
, kuris buvo naudojamas ankstesnėse „Rails“ versijose. Ši nuoroda tada yra aptarnaujama turinio kanalu.
JavaScript failas „Rails“ aplikacijoje ar „Rails“ variklyje yra vienoje iš trijų vietų: app/assets
, lib/assets
arba vendor/assets
. Šios vietos išsamiai paaiškinamos Asset Organization skyriuje „Asset Pipeline Guide“.
Galite nurodyti visą kelią, susijusį su dokumento šaknimi, arba URL, jei pageidaujate. Pavyzdžiui, norėdami susieti su JavaScript failu, kuris yra kataloge, vadinamame javascripts
, esančiame viename iš app/assets
, lib/assets
ar vendor/assets
, tai padarytumėte taip:
<%= javascript_include_tag "main" %>
Tada „Rails“ išvestų script
žymą, panašią į šią:
<script src='/assets/main.js'></script>
Užklausa šiam turiniui tada yra aptarnaujama „Sprockets“ grotuvu.
Norėdami įtraukti kelis failus, pvz., app/assets/javascripts/main.js
ir app/assets/javascripts/columns.js
, tuo pačiu metu:
<%= javascript_include_tag "main", "columns" %>
Norėdami įtraukti app/assets/javascripts/main.js
ir app/assets/javascripts/photos/columns.js
:
<%= javascript_include_tag "main", "/photos/columns" %>
Norėdami įtraukti http://example.com/main.js
:
<%= javascript_include_tag "http://example.com/main.js" %>
3.1.2 Susiejimas su CSS failais naudojant stylesheet_link_tag
stylesheet_link_tag
pagalbininkas grąžina HTML <link>
žymą kiekvienam pateiktam šaltiniui.
Jei naudojate „Rails“ su įjungtu „Asset Pipeline“, šis pagalbininkas sugeneruos nuorodą į /assets/stylesheets/
. Ši nuoroda tada yra apdorojama „Sprockets“ grotuvu. Stilių lapo failas gali būti saugomas vienoje iš trijų vietų: app/assets
, lib/assets
arba vendor/assets
.
Galite nurodyti visą kelią, susijusį su dokumento šaknimi, arba URL. Pavyzdžiui, norėdami susieti su stilių lapo failu, kuris yra kataloge, vadinamame stylesheets
, esančiame viename iš app/assets
, lib/assets
ar vendor/assets
, tai padarytumėte taip:
<%= stylesheet_link_tag "main" %>
Norėdami įtraukti app/assets/stylesheets/main.css
ir app/assets/stylesheets/columns.css
:
<%= stylesheet_link_tag "main", "columns" %>
Norėdami įtraukti app/assets/stylesheets/main.css
ir app/assets/stylesheets/photos/columns.css
:
<%= stylesheet_link_tag "main", "photos/columns" %>
Norėdami įtraukti http://example.com/main.css
:
<%= stylesheet_link_tag "http://example.com/main.css" %>
Pagal numatytuosius nustatymus, stylesheet_link_tag
sukuria nuorodas su rel="stylesheet"
. Galite pakeisti šį numatytąjį nustatymą, nurodydami tinkamą parinktį (:rel
):
<%= stylesheet_link_tag "main_print", media: "print" %>
3.1.3 Susiejimas su paveikslėliais naudojant image_tag
image_tag
pagalbininkas sukuria HTML <img />
žymą nurodytam failui. Pagal numatytuosius nustatymus failai įkeliami iš public/images
.
ĮSPĖJIMAS: Atkreipkite dėmesį, kad turite nurodyti paveikslėlio plėtinį.
<%= image_tag "header.png" %>
Galite nurodyti kelią į paveikslėlį, jei norite:
<%= image_tag "icons/delete.gif" %>
Galite nurodyti papildomų HTML parinkčių raktų rinkinį:
<%= image_tag "icons/delete.gif", {height: 45} %>
Galite nurodyti alternatyvų tekstą paveikslėliui, kuris bus naudojamas, jei vartotojas naršyklėje išjungė paveikslėlius. Jei nepateikiate alternatyvaus teksto aiškiai, jis pagal numatytuosius nustatymus bus failo pavadinimas, didžiosiomis raidėmis ir be plėtinio. Pavyzdžiui, šie du paveikslėlio žymos grąžintų tą patį kodą:
<%= image_tag "home.gif" %>
<%= image_tag "home.gif", alt: "Home" %>
Taip pat galite nurodyti specialų dydžio žymą, formatu "{plotis}x{aukštis}":
<%= image_tag "home.gif", size: "50x20" %>
Be aukščiau minėtų specialių žymių, galite nurodyti paskutinį standartinių HTML parinkčių raktų rinkinį, pvz., :class
, :id
arba :name
:
<%= image_tag "home.gif", alt: "Go Home",
id: "HomeImage",
class: "nav_bar" %>
3.1.4 Susiejimas su vaizdo įrašais naudojant video_tag
video_tag
pagalbininkas sukuria HTML5 <video>
žymą nurodytam failui. Pagal numatytuosius nustatymus failai įkeliami iš public/videos
.
<%= video_tag "movie.ogg" %>
Sukuria
<video src="/videos/movie.ogg" />
Kaip ir image_tag
, galite nurodyti kelią, arba absoliutų, arba santykinį public/videos
katalogo atžvilgiu. Be to, galite nurodyti size: "#{plotis}x#{aukštis}"
parinktį, kaip ir image_tag
. Vaizdo žymos taip pat gali turėti bet kurias HTML parinktis, nurodytas pabaigoje (id
, class
ir kt.).
Vaizdo žyma taip pat palaiko visus <video>
HTML parinktis per HTML parinkčių raktų rinkinį, įskaitant:
poster: "image_name.png"
, suteikia vaizdą, kuris bus rodomas vietoje vaizdo, kol jis pradeda groti.autoplay: true
, pradeda groti vaizdą įkeliant puslapį.loop: true
, kartojasi vaizdas, kai jis pasiekia pabaigą.controls: true
, suteikia naršyklės pateiktus valdiklius, kad vartotojas galėtų sąveikauti su vaizdu.autobuffer: true
, vaizdas iš anksto įkeliamas vartotojui įkeliant puslapį. Jūs taip pat galite nurodyti kelis vaizdo įrašus, kuriuos norite paleisti, perduodami vaizdo įrašų masyvą įvideo_tag
:
<%= video_tag ["trailer.ogg", "movie.ogg"] %>
Tai sukurs:
<video>
<source src="/videos/trailer.ogg">
<source src="/videos/movie.ogg">
</video>
3.1.5 Nuoroda į garso failus naudojant audio_tag
audio_tag
pagalbininkas sukuria HTML5 <audio>
žymą nurodytam failui. Pagal numatytuosius nustatymus failai įkeliami iš public/audios
.
<%= audio_tag "music.mp3" %>
Galite pateikti kelią į garso failą, jei norite:
<%= audio_tag "music/first_song.mp3" %>
Taip pat galite pateikti papildomų parinkčių raktų rinkinį, pvz., :id
, :class
, ir kt.
Kaip ir video_tag
, audio_tag
turi specialias parinktis:
autoplay: true
, pradeda groti garso failą įkeliant puslapįcontrols: true
, suteikia naršyklės teikiamus valdiklius, kad vartotojas galėtų sąveikauti su garso failu.autobuffer: true
, garso failas bus iš anksto įkeltas vartotojui įkeliant puslapį.
3.2 Supratimas apie yield
Išdėstymo kontekste yield
nurodo vietą, kurioje turinys iš vaizdo turėtų būti įterptas. Paprasčiausias būdas tai padaryti yra turėti vieną yield
, į kurį įterpiamas viso šiuo metu atvaizduojamo vaizdo turinys:
<html>
<head>
</head>
<body>
<%= yield %>
</body>
</html>
Taip pat galite sukurti išdėstymą su keliais yield
regionais:
<html>
<head>
<%= yield :head %>
</head>
<body>
<%= yield %>
</body>
</html>
Pagrindinė vaizdo dalis visada bus atvaizduojama bevardžiame yield
. Norėdami atvaizduoti turinį įvardintame yield
, naudokite content_for
metodą.
3.3 Naudodami content_for
metodą
content_for
metodas leidžia įterpti turinį į vardintą yield
bloką jūsų išdėstyme. Pavyzdžiui, šis vaizdas veiktų su ką tik matytu išdėstymu:
<% content_for :head do %>
<title>Paprastas puslapis</title>
<% end %>
<p>Sveiki, "Rails"!</p>
Šio puslapio atvaizdavimo rezultatas su pateiktu išdėstymu būtų šis HTML:
<html>
<head>
<title>Paprastas puslapis</title>
</head>
<body>
<p>Sveiki, "Rails"!</p>
</body>
</html>
content_for
metodas labai naudingas, kai jūsų išdėstyme yra atskiri regionai, tokie kaip šoninės juostos ir poraštės, į kurias turėtų būti įterpti jų pačių turinio blokai. Tai taip pat naudinga įterpti žymes, kurios įkelia puslapio specifinius JavaScript ar CSS failus į pats išdėstymo antraštės dalį.
3.4 Naudodami dalinius šablonus
Dalinių šablonų - paprastai tiesiog vadinamų "dalimis" - yra dar vienas įrankis, skirtas padalinti atvaizdavimo procesą į lengviau valdomus gabalus. Su dalimi galite perkelti kodo, skirtą konkretaus atsakymo dalies atvaizdavimui, į savo atskirą failą.
3.4.1 Dalinių pavadinimai
Norėdami atvaizduoti dalį kaip dalį vaizdo, naudokite render
metodą vaizde:
<%= render "menu" %>
Tai atvaizduos failą, pavadinimu _menu.html.erb
, toje vietoje, kurioje atvaizduojamas šis vaizdas. Pastebėkite pradžioje esantį pabraukimo ženklą: dalys yra pavadinamos su pradiniu pabraukimo ženklu, kad jas būtų galima atskirti nuo įprastų vaizdų, nors joms nurodoma be pabraukimo ženklo. Tai taip pat galioja net tada, kai įkeliate dalį iš kitos aplanko:
<%= render "shared/menu" %>
Tas kodas įkelia dalį iš app/views/shared/_menu.html.erb
.
3.4.2 Dalinių naudojimas, siekiant supaprastinti vaizdus
Vienas būdas naudoti dalis yra traktuoti jas kaip subrutinas: kaip būdą perkelti detales iš vaizdo, kad galėtumėte lengviau suprasti, kas vyksta. Pavyzdžiui, jūsų vaizdas galėtų atrodyti taip:
<%= render "shared/ad_banner" %>
<h1>Produktai</h1>
<p>Čia yra keletas mūsų puikių produktų:</p>
...
<%= render "shared/footer" %>
Čia _ad_banner.html.erb
ir _footer.html.erb
dalys galėtų turėti turinį, kuris bendrinamas daugelyje jūsų programos puslapių. Kai koncentruojatės į konkretų puslapį, jums nereikia matyti šių dalių detalių.
Kaip matyta ankstesniuose šio vadovo skyriuose, yield
yra labai galingas įrankis, skirtas išvalyti jūsų išdėstymus. Atminkite, kad tai yra grynasis "Ruby", todėl jį galite naudoti beveik visur. Pavyzdžiui, galime jį naudoti, siekdami sumažinti formos išdėstymo apibrėžimus keliose panašiose išteklių apibrėžimuose:
users/index.html.erb
<%= render "shared/search_filters", search: @q do |form| %> <p> Vardas turi būti: <%= form.text_field :name_contains %> </p> <% end %>
roles/index.html.erb
<%= render "shared/search_filters", search: @q do |form| %> <p> Pavadinimas turi būti: <%= form.text_field :title_contains %> </p> <% end %>
shared/_search_filters.html.erb
<%= form_with model: search do |form| %> <h1>Paieškos forma:</h1> <fieldset> <%= yield form %> </fieldset> <p> <%= form.submit "Ieškoti" %> </p> <% end %>
PATARIMAS: Jei turinys bendras visose jūsų programos puslapiuose, galite tiesiogiai naudoti dalinius iš maketų.
3.4.3 Dalinių maketai
Daliniui galima naudoti savo maketo failą, kaip ir peržiūrai. Pavyzdžiui, galite iškviesti dalinį taip:
<%= render partial: "link_area", layout: "graybar" %>
Tai ieškos dalinio pavadinimu _link_area.html.erb
ir jį atvaizduos naudodamas maketą _graybar.html.erb
. Atkreipkite dėmesį, kad dalinių maketams taikoma taisyklė dėl priešakyje esančio pabraukimo, kaip ir įprastiems daliniams, ir jie dedami į tą pačią aplanką su daliniu, kuriam jie priklauso (ne į pagrindinį layouts
aplanką).
Taip pat atkreipkite dėmesį, kad būtina aiškiai nurodyti :partial
, kai perduodamos papildomos parinktys, pvz., :layout
.
3.4.4 Vietinės kintamosios perdavimas
Taip pat galite perduoti vietines kintamąsias į dalinius, padarant juos dar galingesnius ir lankstesnius. Pavyzdžiui, galite naudoti šią techniką, kad sumažintumėte dublikavimą tarp naujo ir redagavimo puslapių, išlaikant šiek tiek skirtingo turinio:
new.html.erb
<h1>Nauja zona</h1> <%= render partial: "form", locals: {zone: @zone} %>
edit.html.erb
<h1>Redaguojama zona</h1> <%= render partial: "form", locals: {zone: @zone} %>
_form.html.erb
<%= form_with model: zone do |form| %> <p> <b>Zonos pavadinimas</b><br> <%= form.text_field :name %> </p> <p> <%= form.submit %> </p> <% end %>
Nors tas pats dalinis bus atvaizduojamas abiejuose rodiniuose, veiksmo rodinio submit
pagalbininkas grąžins "Sukurti zoną" naujam veiksmui ir "Atnaujinti zoną" redagavimo veiksmui.
Norėdami perduoti vietinę kintamąją tik tam tikrais atvejais, naudokite local_assigns
.
index.html.erb
<%= render user.articles %>
show.html.erb
<%= render article, full: true %>
_article.html.erb
<h2><%= article.title %></h2> <% if local_assigns[:full] %> <%= simple_format article.body %> <% else %> <%= truncate article.body %> <% end %>
Taip galima naudoti dalinį be visų vietinių kintamųjų deklaravimo.
Kiekvienas dalinis taip pat turi vietinę kintamąją su tuo pačiu pavadinimu kaip dalinis (be priešakyje esančio pabraukimo). Į šią vietinę kintamąją galite perduoti objektą per :object
parinktį:
<%= render partial: "customer", object: @new_customer %>
Daliniui customer
šaltinyje, customer
kintamasis bus nuoroda į @new_customer
iš pagrindinio rodinio.
Jei turite modelio pavyzdį, kurį norite atvaizduoti dalinyje, galite naudoti trumpinį sintaksę:
<%= render @customer %>
Priimant, kad @customer
kintamasis yra Customer
modelio pavyzdys, tai naudos _customer.html.erb
jį atvaizduoti ir perduos vietinę kintamąją customer
į dalinį, kuriame bus nuoroda į @customer
kintamąjį pagrindiniame rodinyje.
3.4.5 Rodomų kolekcijų atvaizdavimas
Daliniai yra labai naudingi atvaizduojant kolekcijas. Kai perduodate kolekciją į dalinį per :collection
parinktį, dalinis bus įterptas kiekvienam kolekcijos nariui:
index.html.erb
<h1>Produktai</h1> <%= render partial: "product", collection: @products %>
_product.html.erb
<p>Produkto pavadinimas: <%= product.name %></p>
Kai dalinis yra iškviestas su daugiskaitos kolekcija, tada atskiriems dalinio pavyzdžiams prieinama kolekcijos narys per kintamąjį, kurio pavadinimas atitinka dalinio pavadinimą. Šiuo atveju dalinis yra _product
, ir _product
dalinyje galite naudoti product
, kad gautumėte atvaizduojamą pavyzdį.
Yra ir trumpinys šiam tikslui. Priimant, kad @products
yra Product
pavyzdžių kolekcija, galite tiesiog parašyti tai index.html.erb
, kad gautumėte tą patį rezultatą:
<h1>Produktai</h1>
<%= render @products %>
Rails nustato dalinio pavadinimą, žiūrėdamas modelio pavadinimą kolekcijoje. Iš tikrųjų, netgi galite sukurti heterogeninę kolekciją ir atvaizduoti ją šiuo būdu, ir Rails pasirinks tinkamą dalinį kiekvienam kolekcijos nariui:
index.html.erb
<h1>Kontaktai</h1> <%= render [customer1, employee1, customer2, employee2] %>
customers/_customer.html.erb
<p>Klientas: <%= customer.name %></p>
employees/_employee.html.erb
<p>Darbuotojas: <%= employee.name %></p>
Šiuo atveju Rails naudos kliento arba darbuotojo dalinius, kaip tinkama kiekvienam kolekcijos nariui.
Jei kolekcija yra tuščia, render
grąžins nil
, todėl paprasta pateikti alternatyvų turinį.
<h1>Produktai</h1>
<%= render(@products) || "Nėra produktų." %>
3.4.6 Vietinės kintamosios
Norėdami naudoti pasirinktinį vietinį kintamąjį daliniame, nurodykite :as
parinktį dalinio iškvietime:
<%= render partial: "product", collection: @products, as: :item %>
Padarius šį pakeitimą, dalinio viduje galite pasiekti @products
kolekcijos egzempliorių kaip item
vietinį kintamąjį.
Taip pat galite perduoti bet kokias vietines kintamąsias bet kuriam daliniui, kurį renderinate, naudodami locals: {}
parinktį:
<%= render partial: "product", collection: @products,
as: :item, locals: {title: "Produktų puslapis"} %>
Šiuo atveju dalinis turės prieigą prie vietinės kintamosios title
su reikšme "Produktų puslapis".
3.4.7 Skaitiklio kintamieji
Rails taip pat suteikia skaitiklio kintamąjį daliniui, kurį iškviečia kolekcija. Kintamasis vadinamas dalinio pavadinimu, prie kurio pridedamas _counter
. Pavyzdžiui, renderinant kolekciją @products
, dalinis _product.html.erb
gali pasiekti kintamąjį product_counter
. Kintamasis indeksuoja, kiek kartų dalinis buvo renderintas uždarame rodinyje, pradedant nuo 0
reikšmės pirmajam renderinimui.
# index.html.erb
<%= render partial: "product", collection: @products %>
# _product.html.erb
<%= product_counter %> # 0 pirmam produktui, 1 antram produktui...
Tai taip pat veikia, kai dalinio pavadinimas yra pakeičiamas naudojant as:
parinktį. Taigi, jei naudojote as: :item
, skaitiklio kintamasis būtų item_counter
.
3.4.8 Tarpiklio šablonai
Taip pat galite nurodyti antrą dalinį, kuris bus renderinamas tarp pagrindinių dalinių, naudodami :spacer_template
parinktį:
<%= render partial: @products, spacer_template: "product_ruler" %>
Rails renderins _product_ruler
dalinį (be jam perduodamų duomenų) tarp kiekvienos poros _product
dalinių.
3.4.9 Kolekcijos dalinio išdėstymai
Renderinant kolekcijas taip pat galima naudoti :layout
parinktį:
<%= render partial: "product", collection: @products, layout: "special_layout" %>
Dalinio išdėstymas bus renderinamas kartu su daliniu kiekvienam elementui kolekcijoje. Esamieji objektas ir objekt_counter kintamieji taip pat bus prieinami išdėstyme, taip pat kaip ir dalinyje.
3.5 Naudojant įdėtus išdėstymus
Gali būti, kad jūsų programa reikalauja išdėstymo, kuris šiek tiek skiriasi nuo įprasto programos išdėstymo, kad palaikytų vieną konkretų valdiklį. Vietoje pagrindinio išdėstymo kartojimo ir redagavimo, tai galite pasiekti naudodami įdėtus išdėstymus (kartais vadinamus sub-šablonais). Štai pavyzdys:
Tarkime, turite šį ApplicationController
išdėstymą:
app/views/layouts/application.html.erb
<html> <head> <title><%= @page_title or "Puslapio pavadinimas" %></title> <%= stylesheet_link_tag "layout" %> <style><%= yield :stylesheets %></style> </head> <body> <div id="top_menu">Viršutinio meniu elementai čia</div> <div id="menu">Meniu elementai čia</div> <div id="content"><%= content_for?(:content) ? yield(:content) : yield %></div> </body> </html>
Puslapiuose, kurie generuojami naudojant NewsController
, norite paslėpti viršutinį meniu ir pridėti dešinį meniu:
app/views/layouts/news.html.erb
<% content_for :stylesheets do %> #top_menu {display: none} #right_menu {float: right; background-color: yellow; color: black} <% end %> <% content_for :content do %> <div id="right_menu">Dešinio meniu elementai čia</div> <%= content_for?(:news_content) ? yield(:news_content) : yield %> <% end %> <%= render template: "layouts/application" %>
Tai viskas. Nauji rodiniai naudos naują išdėstymą, paslėpdami viršutinį meniu ir pridedami naują dešinį meniu "content" div'e.
Šia technika galima pasiekti panašių rezultatų su skirtingais sub-šablonų schemomis. Atkreipkite dėmesį, kad nėra ribos įdėtų lygių. Vienas gali naudoti ActionView::render
metodą per render template: 'layouts/news'
, kad pagrindytų naują išdėstymą pagal News išdėstymą. Jei esate tikri, kad nenaudosite sub-šablono News
išdėstymo, galite pakeisti content_for?(:news_content) ? yield(:news_content) : yield
tiesiog yield
.
Atsiliepimai
Jūs esate skatinami padėti pagerinti šio vadovo kokybę.
Prašome prisidėti, jei pastebite rašybos klaidų ar faktinių klaidų. Norėdami pradėti, galite perskaityti mūsų dokumentacijos prisidėjimo skyrių.
Taip pat gali būti nepilnos informacijos arba informacijos, kuri nėra atnaujinta. Prašome pridėti bet kokią trūkstamą dokumentaciją pagrindiniam. Patikrinkite Edge vadovus pirmiausia, ar problemas jau išspręsta arba ne pagrindinėje šakoje. Patikrinkite Ruby on Rails vadovų gaires dėl stiliaus ir konvencijų.
Jei dėl kokios nors priežasties pastebite kažką, ką reikia ištaisyti, bet negalite patys tai pataisyti, prašome pranešti apie problemą.
Ir galiausiai, bet ne mažiau svarbu, bet koks diskusijos dėl Ruby on Rails dokumentacijos yra labai laukiamos oficialiame Ruby on Rails forume.