web-dev-qa-db-fra.com

Rails: rendre une vue (pas partielle) à partir d'une vue

J'ai un contrôleur qui répond à la fois à html et js. La vue html affiche la page entière (y compris l'en-tête et le pied de page), tandis que la js ne remplace que #main. Mis à part l'en-tête et le pied de page, les deux formats affichent le même contenu. Je peux obtenir cet effet avec trois fichiers:

_show.html.erb
<div>Content!</div>

show.html.erb
<%= render "show" %>

show.js.erb
$("#main").fadeIn("<%= escape_javascript(render 'show') %>");

Cela fonctionne, mais je préférerais que je n'aie pas besoin d'un _show partiel. Malheureusement, cela ne fonctionne pas:

show.html.erb
<div>Content!</div>

show.js.erb
$("#main").fadeIn("<%= escape_javascript(render 'show') %>");

Comme Rails recherchera le show partiel, pas la vue réelle.

Existe-t-il un moyen d'obtenir Rails pour rechercher le fichier de vue, plutôt qu'un fichier partiel?

38
nullnullnull

Le rendu d'une vue non partielle dans une autre vue n'est pas exactement le Rails Way ™. Votre solution actuelle est probablement meilleure, et ce n'est pas une approche inhabituelle. Renommez-la _body, ou autre chose appropriée, si vous vous sentez bizarre que le nom partiel soit le même que l'action.

Cependant, si votre vue peut être partagée, comme cela semble possible dans ce cas, vous pouvez simplement en faire une mise en page.

Ceci est facilité par le fait que, quelque peu contre le principe de la moindre surprise, Rails rendra un modèle html pour une action js si aucune js le modèle existe. Cela signifie que vous pouvez supprimer à la fois le modèle js et le partiel, et simplement créer une mise en page intitulée, par exemple, fadein.js.erb:

# yourviews/show.html.erb
<div>Content!</div>

# layouts/fadein.js.erb
$("#main").fadeIn("<%= escape_javascript(yield) %>");

# YourController.rb
def show
  # ...
  respond_to do |wants|
    wants.html
    wants.js { render :layout => "fadein" }
  end
end
26
numbers1311407

Comme d'autres l'ont mentionné, le rendu d'une autre vue non partielle dans une autre vue n'est pas la méthode Rails), si toutefois vous insistez toujours pour le faire, une méthode est la suivante:

<%= render :file => '<replace with relative/absolute path>' %>
22
Tikiboy

Ce n'est pas une bonne pratique comme vous pouvez le voir dans les commentaires. Rails ont les concepts de vue, partiel et mise en page. Cela dit, la vue est la seule vous ne devez continuer à utiliser qu'une seule fois. Mes suggestions sont donc les suivantes:

  1. Si vous pensez que plusieurs vues supplémentaires peuvent être rendues à l'intérieur de votre vue actuelle, vous recherchez très probablement un layout
  2. Si vous pensez que l'une de vos vues doit être affichée sur plusieurs pages, vous recherchez un partiel
  3. Si cette vue ne doit rendre qu'une seule vue supplémentaire à l'intérieur, et que cette vue ne doit être rendue qu'à l'intérieur de la vue actuelle, vous pouvez choisir l'une des options ci-dessus ou rien de tout cela - c'est tout, allez avec un seul fichier
10
fotanus

il vous suffit de passer un contexte à votre méthode render:

<%= render :template => "show" -%>
4
GMsoF