简体   繁体   中英

Show Rails errors, notices and devise messages in one place

I have my application.html.erb file where this code located:

<% if notice %>
 <p class="notice"><%= notice %></p>
<% elsif alert %>
 <p class="alert"><%= alert %></p>
<% end %>
<%= devise_error_messages! %>

All is great, but form validations are made by using (as usual), this:

<%= form_for @project do |f| %>
    <% if @project.errors.any? %>
        <h2><%= pluralize(@project.errors.count, "error") %> prevented this project from saving:</h2>
        <ul>
            <% @project.errors.full_messages.each do |msg| %>
                <li><%= msg %></li>
            <% end %>
        </ul>
    <% end %>

...

<% end %>

How to include them into main app page & show them always in top?

How to include them into main app page & show them always in top?

This is deeper than just adding a partial (as Umang Raghuvanshi suggested).

The problem is that the errors method is part of an @object , which means you have to make sure you're able to access this object whenever you want to output the errors in application.html.erb .

Partials should never be dependent on @instance_variables - they're meant to be loaded in any part of your app. You can pass local variables to them, allowing you to send predefined data as you need.

In your case, I would use a partial but populate it with a content_for:

--

This is what I'd do:

#app/views/layouts/application.html.erb
<%= render partial: "shared/errors" %>

#app/views/shared/_errors.html.erb
<%= content_tag :div, class: "errors" do %>

    <% if errors.try?(:any?) %>

        <% errors.full_messages.each do |msg| %>
            <%= content_tag :li, msg %>
        <% end %>

    <% else %>

        <% flash = %w(notice error alert) %>
        <% flash.each do |f| %>
            <%= content_tag :div, class: f, flash => [f.to_sym] if flash[f.to_sym] %>
        <% end %>

        <%= devise_error_messages! %>

    <% end %>
<% end %>

#app/views/projects/new.html.erb
<%= form_for @project do |f| %>
   <%= render "shared/errors", locals: {errors: @project.errors} %>
<% end %>

This will allow you to style the .errors div to be absolutely position at the top:

JSFiddle

#app/assets/stylesheets/application.css
.errors { 
   display: inline-block;
   width: 50%;
   position: absolute;
   top: 5%;
}

Extract the code into a partial and include it into your application.html.erb .

_your_partial_name.erb

<% if @project.errors.any? %>
        <h2><%= pluralize(@project.errors.count, "error") %> prevented this project from saving:</h2>
        <ul>
            <% @project.errors.full_messages.each do |msg| %>
                <li><%= msg %></li>
            <% end %>
        </ul>
    <% end %>

application.html.erb

<%= render partial: 'your-partial-name' %>
<% if notice %>
 <p class="notice"><%= notice %></p>
<% elsif alert %>
 <p class="alert"><%= alert %></p>
<% end %>
<%= devise_error_messages! %>

You could also try using flash.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM