Rails: confuso sobre a sintaxe para passar locais para parciais

99

Entender a "mágica" do Rails no que diz respeito a renderizar parciais (e passar locais para eles).

Por que isso funciona:

<%= render "rabbits/form" %>

E este trabalho:

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

mas isso não funciona:

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

Mas isso faz:

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

Além disso, como posso pesquisar essas nuances para não precisar incomodar as pessoas no SO?

Meltemi
fonte
3
Em um comentário abaixo, você estava dizendo que os documentos da API do Rails não são tão pesquisáveis. Você deve tentar este site: apidock.com/rails . Ele também tem ruby ​​e rspec.
ryeguy

Respostas:

152

A resposta curta é que o método render analisa o primeiro argumento que você passa. Se você passar um hash (que inclui :partial => 'foo', :locals => {blah blah blah}), ele passará todos os seus argumentos como um hash e os analisará de acordo.

Se você passar uma string como seu primeiro argumento, ele assume que o primeiro argumento é seu nome parcial e passará o restante como seus locais. No entanto, nessa chamada subsequente, ele realmente atribui :locals => your_locals_argument, que neste caso é o todo :locals => {locals hash}, em vez de apenas {locals hash}; ou seja, você acaba com :locals => {:locals => {locals hash}}, em vez de :locals => {locals hash}.

Portanto, meu conselho é sempre transmitir explicitamente os valores da mesma maneira o tempo todo, e você não terá problemas. Para aprender sobre isso, fui diretamente para o código em si ( actionpack / lib / base.rb , render()método no Rails 2; Rails 3 é diferente). É um bom exercício.

Além disso, não se preocupe em "incomodar" as pessoas no SO. É por isso que este site existe. Eu até aprendi algo com isso.

Doug R
fonte
5

se você precisa especificar: locais, você precisa especificar: parcial ou: modelo

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

Deveria trabalhar

Sethvargo
fonte
tem a ver com a maneira como o ruby ​​avalia o hash se você estiver curioso para isso.
sethvargo
Na verdade, funciona ... como especifiquei na minha pergunta ... mas o que estou querendo saber é por quê? e onde isso está documentado? apenas olhando para a fonte? E, se essa é a única maneira de encontrar e entender sobre essa miríade de nuances em Rails, então estou me perguntando como e onde localizar e interpretar isso da fonte. Não posso simplesmente clicar em "render" e depois detalhar a origem (não com o TextMate de qualquer maneira) ou posso?
Meltemi
1
ah! então você realmente está interessado :). Sim, a única maneira de descobrir essas coisas é a.) Ter um palpite como você e b.) Visualizar o código-fonte. Não tenho ideia de como detalhar a fonte ... desculpe
sethvargo
ok, vou morder ... como você procura esse tipo de coisa? você apenas vasculha o seu clone https://github.com/rails/rails.git? Ou há um modo melhor? Desculpe, mas eu sou relativamente novo no RoR e ainda não encontrei uma maneira boa / fácil / consistente de pesquisar a documentação do Rails ... de forma que EXISTE alguma. http://api.rubyonrails.org/não é facilmente pesquisável. e a fonte do git também não é ... suspiro
Meltemi
Não sou um especialista de forma alguma, mas uso o Aptana Studio. Ele é construído na mesma plataforma do eclipse (se você estiver familiarizado). Ele permite que você "clique" e trace como você disse. Você também pode fazer pesquisa no código e tem um terminal embutido, etc. Cuidado - é um arquivo muito grande
sethvargo
2

Para ser honesto, eu só conheço esses casos de uso, porque tenho me mantido atualizado com o Rails nos últimos dois anos e li os anúncios de que uma nova maneira de fazer isso foi adicionada. Costumo cometer um erro nisso, mas geralmente é facilmente corrigido.

É uma daquelas partes da API Rails que não foi cuidadosamente pensada, se você quer saber. Ele apenas acumulou mais e mais açúcar sintático ao longo dos anos, sem depreciar nenhum dos antigos comportamentos. O método render tem diabetes.

Para piorar ainda mais, a renderização se comporta de maneira diferente no controlador e na visualização. Também examino o conteúdo do primeiro argumento para ver se é um arquivo, modelo, ação ou parcial. Se começar com uma barra, é um arquivo ou algo parecido.

Sou a favor de usar a notação mais curta sempre que possível. Porque as notações curtas comunicam a intenção muito bem. Ao lê-lo, geralmente faz o que você pensa que faz. Escrever parciais não é simples.

iain
fonte
1

Aqui está a fonte do método de renderização de 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

Espero que esta ajuda!

Andrea Salicetti
fonte
Isso ajuda , obrigado! Mas isso não me ajuda a me ajudar ... se é que você me entende ...
Meltemi