42 votes

f.error_messages dans les Rails 3.0

Rails 3.0 obsolète f.error_messages et exige maintenant un plugin pour fonctionner correctement - je toutefois vous voulez apprendre comment afficher les messages d'erreur de la (nouvelle) natif moyen. Je suis le guide de mise en route, qui utilise la méthode dépréciée lors de la mise en œuvre du formulaire de commentaires. Par exemple:

<h2>Add a comment:</h2>
<%= form_for([@post, @post.comments.build]) do |f| %>
  <%= f.error_messages %>
<div class="field">
  <% f.label :commenter  %><br />
  <%= f.text_field :commenter  %>
</div>
<div class="field">
  <%= f.label :body %><br />
  <%= f.text_area :body %>
</div>
<div class="actions">
  <%= f.submit %>
</div>
<% end %>

Ici est la bonne façon de le faire (comme généré par l'échafaudage):

<%= form_for(@post) do |f| %>
  <% if @post.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2>

      <ul>
      <% @post.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>
 . . . 

Je comprends que l'utilisation de l' @post variable dans le dernier exemple, mais ce que variable dois-je faire référence à l'ancienne pour obtenir les messages d'erreur pour le commentaire de la création?

23voto

Nicolas Blanco Points 4815

Le meilleur et propre façon de mettre en œuvre error_messages dans votre formulaire par la mise en œuvre error_messages dans un FormBuilder.

Pour exemple, voici le error_messages méthode que j'ai mis en place pour mon dernier projet. Par implemeting votre propre FormBuilder vous pouvez suivre les règles et les styles de votre webdesigner... Voici un exemple de sortie de la liste d'erreurs à l'ul/li avec certains styles personnalisés :

class StandardBuilder < ActionView::Helpers::FormBuilder
  def error_messages
    return unless object.respond_to?(:errors) && object.errors.any?

    errors_list = ""
    errors_list << @template.content_tag(:span, "There are errors!", :class => "title-error")
    errors_list << object.errors.full_messages.map { |message| @template.content_tag(:li, message) }.join("\n")

    @template.content_tag(:ul, errors_list.html_safe, :class => "error-recap round-border")
  end
end

Alors dans mes formulaires :

= f.error_messages

Et c'est tout.

13voto

Lukas Points 1711

Je suis sûr que tout vous devez faire est de référence @post.comments

Donc, vous pourriez faire quelque chose comme:

<% @post.comments.each do |comment| %>
    <% if comment.errors.any? %>

    <% comment.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
    <% end %>

    <% end %>
<% end %>

Ou il suffit de tirer toutes les erreurs de sortir:

comment_errors = @post.comments.map {|c| c.errors}

et puis parcourir en boucle dans votre logique d'affichage à la sortie de chacun des commentaires des erreurs.

7voto

Justin Tanner Points 5437

Cette fonctionnalité existe dans une seule gemme dynamic_form.

Ajouter les lignes suivantes à votre Gemfile

gem 'dynamic_form'

À partir de la page github:

DynamicForm détient quelques aides méthode pour vous aider à composer avec votre Rails3 des modèles, ils sont:

  • input(record, method, options = {})
  • form(record, options = {})
  • error_message_on(object, method, options={})
  • error_messages_for(record, options={})

Il ajoute également f.error_messages et f.error_message_on de votre formulaire de constructeurs.

3voto

Ben Points 431

Voici ma solution pour l'ensemble de l'erreur de la scène.

J'ai créé une partielle qui utilise simplement une variable de modèle, celui qui passe lors de son affichage:

<%# app/views/errors/_error.html.erb %>

<%= content_for :message do %>
  <% if model.errors.any? %>
    <ul>
      <% model.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
    </ul>
  <% end %>
<% end %>

Vous pouvez facilement ajouter du html dynamique de la classe et/ou de noms de code, basé sur le nom du modèle, ainsi que des génériques.

J'ai des choses de l'installation où mes messages d'erreur rendre dans tous la même place dans un fichier de mise en page:

<%# app/views/layouts/application.html.erb %>

<%= yield :message %>

Si l'on ne voulait pas de cette fonctionnalité, le retrait de la content_for dans le partiel ferait l'affaire.
Alors en tout point de vue que vous voulez, vous pouvez simplement écrire:

<%= render 'errors/error', model: @some_model %>

On pourrait étendre cette par la création d'un partiel qui prend une collecte et exploite l'erreur partielle ci-dessus:

<%# app/views/errors/_collection.html.erb %>

<% collection.each do |model| %>
  <%= render 'errors/error', model: model %>
<% end %>

Rendre avec:

<%= render 'errors/collection', collection: @some_model.some_has_many_association %>

J'aime cette façon. Il est simple, facile à gérer et à maintenir, et incroyablement tweakable.
J'espère que cela aide!

EDIT: Tout en HAML

-# app/views/errors/_error.html.haml

= content_for :message do
  - if model.errors.any?
    %ul
      - model.errors.full_messages.each do |msg|
        %li= msg


-# app/views/layouts/application.html.haml

= yield :message


= render 'errors/error', model: @some_model


-# app/views/errors/_collection.html.haml

- collection.each do |model|
  = render 'errors/errors', model: @some_model


= render 'errors/_collection', collection: @some_model.some_has_many_association

1voto

Matt Points 2617

Je suppose que l' [@post, @post.comments.build] tableau est juste passé de polymorphic_path à l'intérieur d' form_for. Cela génère un sous-chemin d'accès aux ressources pour les commentaires (comme /posts/1/comments dans ce cas). Donc, il semble que votre premier exemple utilise des observations à titre de sous-ressources à des postes, à droite?.

Donc en fait le contrôleur qui sera appelé ici est l' CommentsController. La raison pour laquelle Lukas solution ne fonctionne pas pour vous, peut-être que vous n'utilisez pas @poste.commentaires.construire à l'intérieur de la manette lors de la création du commentaire (il n'a pas d'importance que vous utilisez dans la vue lors de l'appel d' form_for). L' CommentsController#create méthode devrait ressembler à ceci (plus ou moins):

def create
  @post = Post.find(params[:post_id]
  @comment = @post.comments.build(params[:comment])

  if(@comment.save)
    # you would probably redirect to @post
  else
    # you would probably render post#show or wherever you have the form
  end
end

Ensuite, vous pouvez utiliser le code généré par un échafaudage, ne remplacez @post variable d'instance avec @comment de toutes les lignes sauf form_for appel.

Je pense qu'il peut aussi être une bonne idée d'ajouter de l' @comment = @post.comment.build pour la méthode de contrôleur qui affiche ce formulaire et utiliser form_for([@post, @comment], ...) pour garder la forme contenu est affiché dans le formulaire si il y a des erreurs.

Si cela ne fonctionne pas et que vous n'êtes pas en mesure de le comprendre, s'il vous plaît ajouter votre CommentsController#create méthode de la question.

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