J'écris une webapp dans Ruby on Rails 3. Rails 3 échappe automatiquement toutes les chaînes potentiellement mauvaises, ce qui est généralement une bonne chose, mais signifie que si vous assembler vous-même HTML, vous devez appeler html_safe
dessus.Rails 3: Où un assistant utilisant h (c'est-à-dire html_escape) doit-il vivre?
J'ai un modèle de carte, qui a plusieurs champs de texte, dont le contenu n'est pas fiable (peut contenir du code HTML ou un script malveillant). J'ai une fonction qui effectue quelques transformations sur l'un de ces champs de texte, en utilisant d'autres connaissances sur la carte spécifique, pour produire une sortie HTML. Je veux intégrer le HTML produit par cette fonction à plusieurs endroits dans plusieurs parties de mon application.
Conceptuellement, cette aide concerne la vue. Cependant, je ne trouve aucun moyen d'écrire des fonctions dans mes fichiers View; il semble qu'ils doivent aller dans Helpers ou le contrôleur/modèle.
Comme cette fonction est très spécifique à un objet de la carte, la meilleure option serait d'avoir une fonction dans mon modèle de carte card.rb:
class Card < ActiveRecord::Base
[...]
def format(unsafe_text)
initial_text = h unsafe_text # aka html_escape unsafe_text
# assembles HTML output based on initial_text and fields of self
output_text.html_safe!
end
J'aimerais appeler cela en vues assorties en faisant des choses comme:
Rules text: <%= format(@card.rulestext) %>
Cependant, il y a aussi un gros problème ici. Dans le modèle de carte card.rb, je suis en mesure d'utiliser la fonction html_safe!
, mais je ne suis pas en mesure d'utiliser h
ou html_escape
. Il semble que les fonctions h
et html_escape
ne sont disponibles que dans les vues ERB, pas dans les helpers ou les contrôleurs!
Il existe quelques solutions de contournement. Je peux faire format
pas désinfecte son entrée, et aller
Rules text: <%= format(h(@card.rulestext)) %>
Mais c'est à la fois sujettes à dérapages dangereux (un manque h()
et nous avons des problèmes) et est très non-DRY. En ce moment je suis sur un partiel pour avoir accès à la fonction h()
:
(in a normal view)
Rules text: <%= render 'formattext', :text=> @card.rulestext %>
(app/views/shared/_formattext.html.erb)
<%= @card.format(html_escape(text)) %>
Mais cela se sent toujours dangereux. Tout ce que j'ai à faire est de faire un seul appel oublieux à format(sometext)
dans une vue, plutôt que d'appeler render 'formattext', :text=> sometext
, et j'ai un texte sans échappement qui tourne autour.
Y a-t-il une meilleure façon de faire cela? Existe-t-il un moyen d'écrire des fonctions d'aide pour vivre dans la vue plutôt que dans le modèle ou le contrôleur?
Fondamentalement, mon problème était que je ne me rendais pas compte de l'aide Les utilisateurs étaient directement associés à Views. Une fois que vous le savez, il devient plus évident qu'un CardHelper est le bon endroit pour le mettre. – AlexC