Rails: confuso sulla sintassi per il passaggio di locals a partial


99

Comprendere la "magia" di Rails per quanto riguarda il rendering dei partials (e il passaggio dei locali in essi).

Perché funziona:

<%= render "rabbits/form" %>

E questo lavoro:

<%= render "rabbits/form", :parent => @warren, :flash => flash %>

ma questo non funziona:

<%= render "rabbits/form", :locals => { :parent => @warren, :flash => flash } %>

Ma questo fa:

<%= render :partial =>"rabbits/form", :locals => { :parent => @warren, :flash => flash } %>

Inoltre, come posso cercare queste sfumature in modo da non dover disturbare le persone su SO?


3
In un commento qui sotto stavi dicendo che i documenti api di rails non sono così ricercabili. Dovresti invece provare questo sito: apidock.com/rails . Ha anche ruby ​​e rspec.
Ryeguy

Risposte:


152

La risposta breve è che il metodo render esamina il primo argomento che passi. Se passi un hash (che include :partial => 'foo', :locals => {blah blah blah}), allora passerà tutti i tuoi argomenti come hash e li analizzerà di conseguenza.

Se passi una stringa come primo argomento, si presume che il primo argomento sia il tuo nome parziale e passerà il resto come le tue variabili locali. Tuttavia, in quella chiamata successiva, assegna effettivamente :locals => your_locals_argument, che in questo caso è l'intero :locals => {locals hash}, invece che solo {locals hash}; cioè si finisce con :locals => {:locals => {locals hash}}, piuttosto che :locals => {locals hash}.

Quindi il mio consiglio è solo di passare sempre esplicitamente i valori allo stesso modo tutto il tempo, e non avrai problemi. Per saperne di più, sono andato direttamente al codice stesso ( actionpack / lib / base.rb , render()metodo in Rails 2; Rails 3 è diverso). È un buon esercizio.

Inoltre, non preoccuparti di "disturbare" le persone su SO. Ecco perché esiste questo sito. Ho anche imparato qualcosa da questo.


5

se devi specificare: locals, devi specificare: partial o: template

<%= render :partial => "rabbits/form", :locals => {...} %>

dovrebbe funzionare


ha a che fare con il modo in cui ruby ​​valuta l'hash se sei curioso in questo modo.
sethvargo

Effettivamente funziona..come ho specificato nella mia domanda ... ma quello che mi chiedo è perché? e dove è documentato? solo guardando la fonte? E, se questo è l'unico modo per trovare e comprendere questa miriade di sfumature in Rails, allora mi chiedo come e dove procedere per localizzarlo e interpretarlo dalla fonte. Non posso semplicemente fare clic su "rendering" e quindi eseguire il drill-down alla fonte (non con TextMate comunque) o posso?
Meltemi

1
ah! quindi in realtà sei interessato :). Sì, l'unico modo per capire queste cose è a.) Avere un presentimento come hai fatto e b.) Visualizzare il codice sorgente. Non ho idea di come
approfondire

Ok, vi mordo ... come si guardi in alto questo genere di cose? hai appena scavato attraverso il tuo clone https://github.com/rails/rails.git? o c'è un modo migliore? Scusate ma io sono relativamente nuovo per RoR e non ho ancora trovato un buon / facile / modo coerente per cercare documentazione Rails ... tale che non vi È alcuna. http://api.rubyonrails.org/non è facilmente ricercabile. e la fonte di git non è neanche ... sigh
Meltemi

Non sono affatto un esperto, ma uso Aptana Studio. È costruito sulla stessa piattaforma di eclipse (se hai familiarità). Ti permette di "cliccare" e tracciare come hai detto. Puoi anche eseguire la ricerca nel codice e ha un terminale integrato, ecc. Attenzione - è un file piuttosto grande
sethvargo

2

Per essere onesto, conosco solo questi casi d'uso, perché ho tenuto il passo con Rails negli ultimi due anni e ho letto gli annunci che è stato aggiunto un nuovo modo di farlo. Spesso faccio un errore io stesso, ma di solito è facilmente corretto.

È una di quelle parti dell'API di Rails che non è stata studiata a fondo, se me lo chiedi. Ha semplicemente accumulato sempre più zucchero sintattico nel corso degli anni, senza deprecare nessuno dei vecchi comportamenti. Il metodo di rendering ha il diabete.

A peggiorare le cose, il rendering si comporta in modo diverso nel controller e nella vista. Esamina anche il contenuto del primo argomento per vedere se è un file, un modello, un'azione o una parte. Se inizia con una barra, allora è un file o qualcosa del genere.

Sono favorevole a utilizzare la notazione più breve quando possibile. Perché le annotazioni brevi comunicano abbastanza bene l'intento. Quando lo leggi, di solito fa quello che pensi che faccia. Scrivere i parziali non è semplice.


1

Ecco la fonte del metodo di rendering da http://api.rubyonrails.org/classes/ActionView/Rendering.html#method-i-render :

def render(options = {}, locals = {}, &block)
  case options
  # Here is your last case
  when Hash
    if block_given?
      _render_partial(options.merge(:partial => options.delete(:layout)), &block)
    elsif options.key?(:partial)
      _render_partial(options)
    else
      template = _determine_template(options)
      lookup_context.freeze_formats(template.formats, true)
      _render_template(template, options[:layout], options)
    end
  when :update
    update_page(&block)
  else
    # here the first three cases
    _render_partial(:partial => options, :locals => locals)
  end
end

Spero che questo aiuto!


Questo aiuta , grazie! Ma non mi aiuta ad aiutare me stesso ... se sai cosa intendo ...
Meltemi
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.