Rails: zdezorientowani o składni przekazywania mieszkańców do części

Zrozumienie Rails "magii" w odniesieniu do renderowania częściowych (i przekazywania do nich lokalnych).

Dlaczego to działa:

<%= render "rabbits/form" %>

I to dzieło:

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

Ale to działa a nie:

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

Ale tak jest:

<%= render :partial =>"rabbits/form", :locals => { :parent => @warren, :flash => flash } %>
Poza tym, jak mogę sprawdzić te niuanse, żeby nie przeszkadzać ludziom na S. O.?
Author: Meltemi, 2010-12-09

4 answers

Krótka odpowiedź to metoda render patrzy na pierwszy argument, który podajesz. Jeśli przekazujesz hash (który zawiera :partial => 'foo', :locals => {blah blah blah}), to przekaże on wszystkie twoje argumenty jako hash i odpowiednio je przetworzy.

Jeśli przekazujesz ciąg znaków jako pierwszy argument, zakłada on, że pierwszy argument jest twoją częściową nazwą, a reszta będzie przekazywana jako Twoje lokalne. Jednak w tym kolejnym wywołaniu faktycznie przypisuje :locals => your_locals_argument, które w tym przypadku jest Całym :locals => {locals hash}, a nie tylko {locals hash}; tj. kończy się :locals => {:locals => {locals hash}}, a nie :locals => {locals hash}.

Więc moja rada jest po prostu zawsze wyraźnie przekazać wartości w ten sam sposób cały czas, i nie będzie miał problemów. Aby się o tym dowiedzieć, przeszedłem bezpośrednio do samego kodu (actionpack/lib/base.rb, render() metoda w Rails 2; Rails 3 jest inny). To dobre ćwiczenie.

Ponadto, nie martw się o" zawracanie głowy " ludziom na tak. Dlatego ta strona istnieje. Nauczyłem się czegoś z tego.

 150
Author: Doug R,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-12 06:08:41

Jeśli chcesz podać: locals, musisz podać: partial lub: template

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

Powinno działać

 5
Author: sethvargo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-23 20:46:38

Aby być uczciwym, wiem tylko o tych przypadkach użycia, ponieważ nadążam za Rails ' ami przez ostatnie kilka lat i czytam zapowiedzi, że został dodany nowy sposób. Sam często popełniam w nim błąd, ale zazwyczaj łatwo go naprawić.

To jedna z tych części rails API, która nie została dokładnie przemyślana, jeśli O mnie chodzi. Po prostu zgromadził coraz więcej cukru składniowego na przestrzeni lat, bez deprecjacji żadnego ze starych zachowań. Na metoda rendera ma cukrzycę.

Aby było jeszcze gorzej, renderowanie zachowuje się inaczej w kontrolerze i widoku. Patrzę również na zawartość pierwszego argumentu, aby zobaczyć, czy jest to plik, szablon, akcja czy częściowa. Jeśli zaczyna się od ukośnika, to jest to plik, czy coś w tym stylu.

Jestem za używaniem krótszej notacji w miarę możliwości. Ponieważ krótkie notacje dość dobrze przekazują intencje. Podczas czytania zwykle robi to, co myślisz, że robi. Pisanie to nie to prosto do przodu.

 2
Author: iain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-09 21:40:55

Oto źródło metody renderowania z 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
Mam nadzieję, że to pomoże!
 1
Author: Andrea Salicetti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-09 20:22:45