Rails 5 redirect notice style - ruby-on-rails

When a user creates a ticket my site redirects to the ticket and displays a notice that informs the user it has been created. At the moment it is a standard notice with no styling.
This is the block that redirects - I need to add a class to the notice. How can this be achieved?
redirect_to #ticket, notice: 'Ticket was successfully created.'

Add a class to a tag, maybe a div, and then wrap your notice there, like:
<div class="notice">
<%= notice %>
</div>
But what's usually done, is to assign a class to the html tag dinamycally, this way if the flash message is notice or other, then you have the styles defined for each of them, like:
<% flash.each do |key, message| %>
<p class="<%= key %>">
<%= message %>
</p>
<% end %>

In rails 5 you can use 'add_flash_types' method. Just add it to ApplicationController and include the types you want:
class ApplicationController < ActionController::Base
add_flash_types :success, :warning, :danger, :info
on your controller use the appropriate type instead of 'notice':
redirect_to #ticket, success: 'Ticket was successfully created.'
and then you can automate your view:
<% flash.each do |message_type, message| %>
<div class="alert alert-<%= message_type %>">
<%= message %>
</div>
<% end %>
source:
http://api.rubyonrails.org/v5.1/classes/ActionController/Flash/ClassMethods.html#method-i-add_flash_types

Related

How do I print validation messages for form_for :post structure?

I have something like
<div class="userInput">
<%= form_for :scribble do |f| %>
<%= f.text_area :scribble, cols: 65, rows: 4,:maxlength => 255%>
<%= f.submit %>
<% end %>
</div>
1)My Scribble model has min and max character length validation, now how do I print the error messages here. If it is an instance variable I know how to print, but this is a symbol.
2) This code is present in the application.html.erb. I am not able to understand how do I move it into a view of Scribble controller other than appliation. Problem is this form is not independent, it is a part of action index display of controller Scribbles,(and the form should be displayed always) and action index is already doing listing of scribbles.
Controller
def index
#scribbles = Scribble.order("scribbles.scribble DESC").all
end
def show
end
def new
end
def create
#scribble = Scribble.new(profile_params)
#scribble.likes =#scribble.dislikes =#scribble.shares=0;
#scribble.save
#scribbles = Scribble.order("scribbles.scribble DESC").all
render :index
end
Here how i out-put any errors or validation messages:
Controller:
def create
#scribble = Scribble.new(profile_params)
#scribble.likes =#scribble.dislikes =#scribble.shares=0;
if #scribble.save
flash[:notice] = "Scribble is successfully created"
redirect_to root_url
else #
render 'index'
end
end
Views:
Create a partial to show error messages if any e.g _error_messages.html.erb
<% if object.errors.any? %>
<div id="error_explanation">
<div class="alert callout text-center" data-closable>
<p><strong>This form contains <%= pluralize(object.errors.count, 'error') %>.</strong></p>
<ul>
<% object.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
<button class="close-button" aria-label="Dismiss alert" type="button" data-close>
<span aria-hidden="true">×</span>
</button>
</div>
</div>
<% end %>
Render errors:
Now you can call <%= render 'layouts/error_messages', object: #scribble %> and put it anywhere in your views to render the errors validation. note: the object is passed, so it can be re-use to any form. credits to Hartl Tutorial.

Raw Database content showing up in Rails View

You can see here that it seems like the raw contents of my DB are being printed to the page. I can't see anywhere in my code why there would be the raw output of the db printed to the view. Here is the code for the index view:
<div class="main">
<div="messages">
<%=#messages.each do |t|%>
<h2 class="subject"><%=t.subject%></h2>
<p class="content"><%=t.content%></p>
<% end %>
<%=link_to "Create Message", edit_path%>
</div>
</div>
The Create Form/View:
<div class="formWrapper">
<%= form_for #messages do |t|%>
<div class ="Inputs">
<%=t.text_field :subject%><br>
<%=t.text_area :content%>
<div class="submit">
<%=t.submit "Submit"%>
</div>
<%end%>
</div>
</div>
The Controller:
class MessagesController < ApplicationController
def index
#messages=Message.all
end
def new
#messages=Message.new
end
def create
#messages = Message.new(message_params)
if #messages.save
redirect_to '/'
else
render 'new'
end
end
private
def message_params
params.require(:message).permit(:content, :subject)
end
end
you don't need the = here: <%=#messages.each do |t|%>, the equals sign is telling erb to show every message on the view.
<% %>
Will execute Ruby code with no effect on the html page being rendered. The output will be thrown away.
<%= %>
Will execute Ruby code and insert the output of that code in place of the <%= %>
example...
<% puts "almost" %> nothing to see here
would render as
nothing to see here
however
<%= puts "almost" %> nothing to see here
would render as
almost nothing to see here
Look at <% %>(without equal) in ruby erb means?

How do I get my Flash Message to show using bootstrap?

I have already imported bootstrap and I'm using the 'bootstrap-sass' gem and devise gem. The problem is My rails app shows the the right message like if am signed in and i try to sign up it shows the message 'You are already signed in.' but without the color around the message like yellow or red or any color.
<div class="container">
<% flash.each do |name, msg| %>
<%= content_tag(:div, msg, class: "alert alert-#{name}") %>
<% end %>
</div>
When I inspect the element in chrome after it rendered I get 'class="alert alert-alert"'
In my code above the "alert alert-#{name}" the name is the key which should change to info, success, or warning or danger. but it keeps changing to alert which bootstrap doesn't have. How can i fix this?
You can fix this by setting your flash message in your controller as flash[:success], flash[:info], flash[:warning] or flash[:danger], as opposed to flash[:alert].
For Devise, you will need to copy the Devise controllers into your Rails application to override these values. Alternatively, you can display the Bootstrap alerts manually if flash[:notice] or flash[:alert] are set:
<% if flash[:notice] %>
<div class="alert alert-info">
<%= flash[:notice] %>
</div>
<% end %>
<% if flash[:alert] %>
<div class="alert alert-danger">
<%= flash[:alert] %>
</div>
<% end %>

Flash messages appearing twice in rails

My flash messages are appearing twice and my web research tells me this is due to render and redirect displaying the messages. I think I need to use flash.now[] or flash[] somewhere to sort this but I can't work out where it needs to go
guidelines_controller.rb
def update
#guideline = Guideline.find(params[:id])
respond_to do |format|
if #guideline.update_attributes(params[:guideline])
#guideline.update_attribute(:updated_by, current_user.id)
format.html { redirect_to #guideline, notice: 'Guideline was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "show" }
format.json { render json: #guideline.errors, status: :unprocessable_entity }
end
end
end
layouts/application.html.erb
<div class="container">
<% flash.each do |type, message| %>
<div class="alert <%= flash_class type %>">
<button class="close" data-dismiss="alert">x</button>
<%= message %>
</div>
<% end %>
</div>
application_helper.rb
def flash_class(type)
case type
when :alert
"alert-error"
when :notice
"alert-success"
else
""
end
end
guideline_controller.rb
def show
#guideline = Guideline.find(params[:id])
if #guideline.updated_by
#updated = User.find(#guideline.updated_by).profile_name
end
if User.find(#guideline.user_id)
#created = User.find(#guideline.user_id).profile_name
end
respond_to do |format|
format.html # show.html.erb
format.json { render json: #guideline }
end
end
You can do something like this in order to save some lines of code, and display the messages just once:
<%- if flash.any? %>
<%- flash.keys.each do |flash_key| %>
<%- next if flash_key.to_s == 'timedout' %>
<div class="alert-message <%= flash_key %>">
<a class="close" data-dismiss="alert" href="#"> x</a>
<%= flash.discard(flash_key) %>
</div>
<%- end %>
<%- end %>
By using flash.discard, you show the flash message an avoid rendering twice
Just putting this here for anyone else having trouble.
I had flash messages appearing twice because I had something in application.html.erb telling my app to display flash messages, but I had previously generated views with rails generate scaffold posts etc, so that had automatically added the flash messages to all the views.
So the solution was to remove them from the views.
Here's a great tutorial that demonstrates removal for just one model/view
So basically, if you have something like this in your application.html.erb:
<% if notice %>
<p class="alert alert-success"><%= notice %></p>
<% end %>
<% if alert %>
<p class="alert alert-danger"><%= alert %></p>
<% end %>
Then simply remove the equivalent from each of the views. I.e. remove this line from the top of each view
<p id="notice"><%= notice %></p>
I was also having the same issue and also due to another call of <%= render 'shared/alerts' %> later after my check for flash. I liked #rorra's idea of doing a flash_key. But here in the year 2020, it wasn't working as #tessad stated. It would show the message, but not format in bootstrap correctly.
I was able to change their code to work with BootStrap 4. It even dismisses as it is supposed to. The three things that needed to change were all dealing with the class of the div used to display the flash notice.
<div class="alert-message <%= flash_key %>">
alert-message becomes just alert, and the flash_key has to have alert- before it.
<div class="alert alert-<%= flash_key %>">
The last thing is I was sending it to the view from the controller as flash[:notice], which is not a recognized bootstrap alert. When I changed it to flash[:warning] it showed up correctly.
Here is the final code that worked for me. Putting it here in case anyone needs it now 7 years after the initial answer was given.
<div id="container">
<%- if flash.any? %>
<%- flash.keys.each do |flash_key| %>
<%- next if flash_key.to_s == 'timedout' %>
<div class="alert alert-<%= flash_key %>">
<a class="close" data-dismiss="alert" href="#"> x</a>
<%= flash.discard(flash_key) %>
</div>
<%- end %>
<%- end %>
</div>

DEVISE - successful message when ask for a new password

I'm using the Devise gem and I just would like to show a successful message when someone ask for a new password (if forgotten). Currently, when submitted, the button redirects to sign_in without any message.
Thank you
Rather than using the flash and trying to work out how Devise does it's thing (not for the faint-hearted) by extending its controllers, how about checking the referrer, and displaying a message in the view if it matches your 'remind me of my password' path?
In the view:
<% if request.env['HTTP_REFERER'] == "/give/me/a/new/password" %>
<h2>Your password stuff is all good now.</h2>
<% end %>
flash[:success] = "Something Something"
Devise rolls out it's own alert messages (and they can be edited in the config/locales/devise.en.yml and written for other languages), you just need to catch them.
One way is to add a layout/_messages partial:
<% flash.each do |name, msg| %>
<% if msg.is_a?(String) %>
<div class="alert alert-<%= name %>">
<a class="close" data-dismiss="alert">×</a>
<%= content_tag :div, msg, :id => "flash_#{name}" %>
</div>
<% end %>
<% end %>
and render it in application.html.erb:
<%= render 'layouts/messages' %>
This has the benefit of catching all (devise and other) messages and playing nicely with bootstrap alert classes (if you use were using bootstrap).
.
Or if you are using slim:
- flash.each do |name, msg|
- if msg.is_a?(String)
div class="alert alert-#{name}"
a class="close" data-dismiss="alert"
| ×
= content_tag :div, msg, :id => "flash_#{name}"
= render 'layouts/messages'
.
Devise uses the rails standard :notice rather than :success but a you can add the success (green) styling to your css/scss (e.g. to bootstrap_and_overriders.css.scss):
.alert-alert {
#extend .alert-error
}
.alert-notice {
#extend .alert-success
}

Resources