Considere o seguinte cenário básico …
Uma visualização com duas colunas:
um com links de instâncias de modelo de categoria
o outro vazio, mas ansioso para mostrar todas as instâncias de Item pertencentes a cada categoria.
E você quer mostrar tudo isso sem recarregar a página. Eu nunca tinha jogado muito com parciais em Rails, mas eles são realmente muito convenientes.
Então, eu tenho meu método de índice
#items_controller.rb
def index
@items = Item.all
@categories = Category.all
end
Por uma questão de brevidade, simplificarei as visualizações. Dessa forma, você também pode entender a ideia e aplicá-la às suas próprias visões.
A visualização do índice contém duas chamadas de renderização
<!-- items/index.html.erb -->
<div class="grid">
<%= render 'sidebar_menu' %>
<%= render partial: 'item_grid', locals: { items: @items} %>
</div>
Os links de categoria na sidebar_menu
parcial são mais ou menos como o seguinte:
<%= link_to cat.name, fetch_items_path(:cat_id => cat.id), :remote => true %>
fetch_items_path
é a rota que leva ao nosso método javascript personalizado, que será descrito a seguir.
#config/routes.rb
...
get "/fetch_items" => 'items#from_category', as: 'fetch_items'
Para mais informações sobre como construir rotas personalizadas, verifique a incrível documentação do Rails.
A é a parte mais importante aqui, ela permite todo o negócio Ajax em primeiro lugar.:remote => true
A item_grid
parcial se parece com:
<div>
<div id="items_grid" >
<%= render partial: 'items_list', locals: {items: items} %>
</div>
</div>
O subparcial items_list
apenas renderiza uma lista de caixas div para mostrar nossas instâncias de Item.
<% items.each do |item| %>
<div class="item_box">
...
</div>
<% end %>
Agora precisamos do método que fará a mágica do AJAX. Para simplificar, você poderia ter algo assim:
#items_controller.rb
def from_category
@selected = Item.where(:category_id => params[:cat_id])
respond_to do |format|
format.js
end
end
Observe o tipo de formato, não há visão html porque não precisamos dela. Estamos passando por JS.
Portanto, precisamos criar um arquivo javascript, que irá preencher novamente o div na segunda coluna.
//views/items/from_category.js.erb
$("#items_grid").html("<%= escape_javascript(render partial: 'items_list', locals: { items: @selected } ) %>");
Vamos examinar essa linha com cuidado.
Estou renderizando o mesmo parcial que estava renderizando em items # index, e a variável local para o partial agora é a matriz de instâncias de Item que correspondem a uma determinada categoria. A diferença é que estou fazendo isso por meio de AJAX, portanto, não há necessidade de recarregar a página inteira.