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.