127 votes

Comment rendre un partiel d'un format différent dans Rails ?

J'essaie de générer une réponse JSON qui inclut du HTML. Ainsi, j'ai /app/views/foo/bar.json.erb :

{
  someKey: 'some value',
  someHTML: "<%= h render(:partial => '/foo/baz') -%>"
}

Je veux qu'il rende /app/views/foo/_baz.html.erb mais il ne rendra que /app/views/foo/_baz.json.erb . Passing :format => 'html' n'aide pas.

0 votes

Le titre de la question est beaucoup plus général que le problème particulier de James. Si vous cherchez d'autres solutions, jetez un coup d'œil ici : stackoverflow.com/questions/7616097/

106voto

Tim Haines Points 571

À partir de la version 3.2.3 de Rails, lors de l'appel à render :partial (qui ne fonctionne qu'en dehors de l'environnement respond_to bloc).

render formats: [ :html ]

au lieu de

render format: 'html'

0 votes

Je suppose qu'il peut y avoir différentes "meilleures" réponses en fonction du contexte, donc il est difficile de voter positivement sur cette question, mais cela a répondu à mon besoin de rendre facilement un modèle HTML à partir d'un modèle RJS du même nom après avoir espéré qu'une :format fonctionnerait. Merci !

1 votes

Cela fonctionne également pour Rails 5.0.2. Toutefois, notez que vous devrez peut-être aussi spécifier l'option :content_type dans certains cas - par exemple, pour rendre un modèle HTML à l'intérieur d'un système de gestion de l'information. format.pdf ne peut se faire qu'avec render "template", formats: [:html], content_type: "text/html" . J'en ai besoin car je permets le téléchargement direct d'échantillons de mes livres uniquement pour les membres de ma liste d'adresses électroniques - les visiteurs réguliers reçoivent un formulaire d'inscription à la place.

64voto

Sam Stokes Points 7118

Quel est le problème avec

render :partial => '/foo/baz.html.erb'

? Je viens d'essayer de rendre un HTML ERB partiel à partir d'un modèle Atom builder et cela a bien fonctionné. Pas de manipulation de variables globales nécessaire (oui, je sais qu'elles ont un "@" devant elles, mais c'est ce qu'elles sont).

Votre with_format &block approche est cool cependant, et a l'avantage de ne spécifier que le format, alors que l'approche simple spécifie également le moteur de modèle (ERB/builder/etc).

0 votes

C'est vraiment l'approche la plus simple, et elle fonctionne parfaitement pour moi.

26 votes

Le seul inconvénient est que si votre partiel rend d'autres partiels, il échouera à moins que vous ne changiez tous vos appels de partiels de rendu pour inclure le ".html.erb" dans leur nom.

0 votes

+1 bien sûr, mais le fait de devoir spécifier le moteur de template, combiné à la préoccupation soulevée par chrisbailey au sujet des partiels imbriqués, me rend prudent.

32voto

zgchurch Points 1231

Pour Rails 3, le bloc with_format fonctionne, mais c'est un peu différent :

  def with_format(format, &block)
    old_formats = formats
    self.formats = [format]
    block.call
    self.formats = old_formats
    nil
  end

0 votes

Fonctionne aussi avec rails 3.2.0 :)

30voto

James A. Rosen Points 25774

Construire sur Réponse de roninek J'ai trouvé que la meilleure solution était la suivante :

dans /app/helpers/application.rb :

def with_format(format, &block)
  old_format = @template_format
  @template_format = format
  result = block.call
  @template_format = old_format
  return result
end

Dans /app/views/foo/bar.json :

<% with_format('html') do %>
  <%= h render(:partial => '/foo/baz') %>
<% end %>

Une solution alternative serait de redéfinir render d'accepter un :format paramètre.

Je n'ai pas pu obtenir render :file pour travailler avec les locaux et sans les aléas du chemin.

9 votes

Trop bricolé à mon goût. Il est préférable de spécifier l'extension entière.

1 votes

Pour les rails 3, voir la réponse de zgchurch.

25voto

Tony Stubblebine Points 221

Dans Rails 3, la vue possède un tableau de formats, ce qui signifie que vous pouvez la configurer pour rechercher [:mobile, :html]. Si vous définissez cette option, la vue recherchera par défaut les modèles :mobile, mais reviendra aux modèles :html. Les effets de cette configuration se répercuteront sur les partiels internes.

La meilleure façon, mais encore imparfaite, que j'ai trouvée pour régler cela était de mettre cette ligne en haut de chaque modèle mobile complet (mais pas les partiels).

<% self.formats = [:mobile, :html] %>

L'inconvénient est que vous devez ajouter cette ligne à plusieurs modèles. Si quelqu'un connaît un moyen de définir cette ligne une seule fois, à partir d'application_controller.rb, j'aimerais le savoir. Malheureusement, il n'est pas possible d'ajouter cette ligne à votre mise en page mobile, car les modèles sont rendus avant la mise en page.

0 votes

Merci d'avoir expliqué cela. J'ai fini par l'utiliser ailleurs : stackoverflow.com/questions/47459724/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X