How to create alert with redirect_to - ruby-on-rails

Hi I want to create an success alert when a gossip was created and return on my home page or put's an danger alert when the validation fail
I've just succeeded to setup the error alert.
Here is my gossip controller :
class GossipsController < ApplicationController
def index
#gossips = Gossip.all
end
def show
#gossip = Gossip.find(params[:id])
end
def new
#error = false
end
def create
#gossip = Gossip.new(title: params[:title], content: params[:content], user: User.find(182))
if #gossip.save
redirect_to root_path
else
#error = true
render "new"
end
end
end
And here it's my view of new :
<% if #error %>
<div class="alert alert-danger alert-dismissible fade show" role="alert">
<strong>Error</strong>
<ul>
<% #gossip.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<% end %>
<h2>Create your own gossip !</h2> <br><br>
<%= form_tag url_for(action: 'create'), method: "post" do %>
<%= label_tag 'Title :' %> <br>
<%= text_field_tag 'title'%> <br><br>
<%= label_tag 'Content :' %> <br>
<%= text_area_tag 'content'%> <br><br>
<%= submit_tag "Create Gossip" %>
<% end %>
I've try to do same for the success alert but if i put a #success = true in the controller and <% if #success %> in the index view that don't work. I don't have any ideas.
Tell me if you need some part of my code.
I've tried with flash but that doesn't worked and whatever i want the same style with the error and success alert

create flash message partial app/views/layouts/_flash.html.erb
(please give filename with underscore since it partial)
<% flash.each do |key, value| %>
<div class="alert alert-<%= key == "success" ? "success" : "danger" %>">
<%= value %>
</div>
<% end %>
add partial to your app/views/layouts/application.html.erb
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
...
<%= render 'layouts/flash' %>
<%= yield %>
</Body>
</html>
in your controller
def create
#gossip = Gossip.new(title: params[:title], content: params[:content], user: User.find(182))
if #gossip.save
flash[:success] = 'success'
redirect_to root_path
else
flash[:danger] = #gossip.errors.full_messages[0]
render "new"
end
end

Don't write in every form view instead of that you can just write common code to show the alerts related to success or error and then use that from any controllers :-
## app/views/layouts/application.html.erb
<html>
<body>
<%= render 'layouts/header' %> ## your header layout
<div class="container">
<% flash.each do |key, value| %>
<div class="alert <%= flash_class(key) %>"><%= value.try(:html_safe) %></div>
<% end %>
<%= yield %>
<%= render 'layouts/footer' %> ## your footer layout
</div>
</body>
</html>
Use helper to get correct bootstrap classes according to your requirement :-
module ApplicationHelper
def flash_class(level)
level = level.to_sym
case level
when :notice then "alert-info"
when :success then "alert-success"
when :error then "alert-danger"
when :alert then "alert-warning"
end
end
end
And then use above code in any controller :-
if #gossip.save
flash[:success] = "Your success custom message."
redirect_to root_path
else
err_msg = ""
flash.now[:error] = #gossip.errors.full_messages.map{|msg| err_msg << "#{msg} <br> "}
render "new"
end
Note :- Use flash when you are redirecting, and flash.now when you are rendering.
edited content :-
Add <br> tag in error messages before showing and then on view page add .html_safe for showing every error in next line. This hack should be work and user will able to see all error messages related to object.
flash.now[:error] = #gossip.errors.full_messages.map{|msg| err_msg << "#{msg} <br> "}
In view
<% flash.each do |key, value| %>
<div class="alert <%= flash_class(key) %>"><%= value.try(:html_safe) %></div>
<% end %>

Related

Rails show error message of another model

I have a html partial that displays errors:
shared/model_errors.html.erb
<% model.errors.full_messages.each do |msg| %>
and I render it at top of each html file like
<%= render partial: 'shared/model_errors',locals: {model: #model_to_check_errors}%>
This is working fine for most of them.
Let's say that I'm on the show.html.erb template of the ConversationsController, and I have there a form_tag which submits messages to the MessagesController. If the submitted message is empty, the MessagesController won't allow it to be saved, because it has validation errors. How do I display those validations errors in my show.html.erb, considering I don't have access to the #message object of the create action of the MessagesController. Is there any way to add the error message to the ConversationsController? They will be displayed that way.
Edit:
show.html.erb of the ConversationsController
<div class="container nav_exp">
<%= render partial: 'shared/model_errors',locals: {model: #???}%>
<div class="ch-body">
<div class="col-md-12 bg-white ">
<div class="chat-message">
<ul class="chat" id="messages">
<% if #messages != nil %>
<%= render partial: 'conv_message', collection: #messages,:as => :message%>
<% else %>
<div class="panel-body hidden"></div>
<%end%>
</ul>
</div>
<%=form_tag(messages_path, :method=>'post',authenticity_token: true,remote: true) do%>
<div class="chat-box bg-white">
<div class="input-group">
<%= text_field_tag :body,"", id:"message_body",class: "form-control border no-shadow no-rounded", placeholder: "Type your message here"%>
<%= hidden_field_tag :conversation_id, #conversation.id %>
<%= hidden_field_tag :receiver, #other.id %>
<span class="input-group-btn">
<%= submit_tag 'Submit', class: "btn btn-success no-rounded" %>
</span>
</div><!-- /input-group -->
</div>
<% end %>
</div>
</div>
</div>
The create method of the MessagesController - messages_path
def create
message = Message.new(message_params)
message.user = current_user
if message.save
...
else
puts 'not working'
'I think 1 solution would be to add here flash messsages'
end
end
private
def message_params
params.permit(:body, :conversation_id, :receiver)
end

how to pass key value through [action].js.erb remote: true ajax

Here is how I display my flash messages using key value.
application_html.erb
<div class="container-fluid">
<% flash.each do |message_type, message| %>
<div class="alert alert-<%= message_type %>" data-turbolinks="false">
<a class="close lay" data-dismiss="alert">&#215</a>
<% if message.is_a?(String) %>
<div id="flash_<%=message_type%>">
<%= sanitize(message) %>
</div>
<% end %>
</div>
<% end %>
</div>
Now I have in my controller:
def saved
...
respond_to do |format|
format.js
end
end
And in my form:
<%= link_to... remote: true, method: :put %>
Now in my saved.js.erb file, I have the following:
<% if request.put? %>
<% response = current_user.saved_articles.new(article: #article) %>
<% if !response.valid? %>
FLASH SOMETHING HERE
<% else %>
<% response.save %>
FLASH SOMETHING HERE
<% end %>
<% else request.delete? %>
<% current_user.saveds.delete(#article) %>
FLASH SOMETHING HERE
<% end %>
How do I pass notice: "You have saved this article" and notice: "You have unsaved this article" ?
is saved action actually saving? if you're saving a record (or updating or deleting) you should (don't have to) do this using create and update and destroy actions. Put everything into one action isn't the proper way to do it, even when you're manipulating db records... why not proper CRUD:
def create
# create logic
render js: { model: #your_model, status: #your_model.persisted? : :ok, :unprocessable_entity }
end
(and other actions)
and then in your js, you can ask the async call status, and build the messaging from there.
Store the flash message component in a partial and call it in js.erb file, remove it after few seconds if you wish to do so.
One small note if you plan to name the partial as _flash.html.erb, flash object value would become nil in the partial's:
I found out that the reason this was not working for me was that I had
named my partial flash. Apparently Rails creates a local variable for
the partial using the partial's name (without the "" character.) So I
had a variable clash. As soon as I change the name of the partial to
something other than _flash everything worked perfectly. I found the
answer here: Rails flash[:notice] always nil
-from this SO post
application_html.erb:
<div class="container-fluid">
<%= render partial: 'shared/flash_messages' %>
</div>
shared/_flash_messages.html.erb
<% flash.each do |message_type, message| %>
<div class="alert alert-<%= message_type %> flash_messages" data-turbolinks="false">
<a class="close lay" data-dismiss="alert">&#215</a>
<% if message.is_a?(String) %>
<div id="flash_<%=message_type%>">
<%= sanitize(message) %>
</div>
<% end %>
</div>
<% end %>
controller.rb
def saved
if saved?
flash[:success] = "You have saved this article"
else
flash[:danger] = "You have unsaved this article"
end
respond_to do |format|
format.js
end
end
saved.js.erb
<% if request.put? %>
<% response = current_user.saved_articles.new(article: #article) %>
<% if !response.valid? %>
// append to any element
$('body').append('<%= j render partial: "shared/flash_messages"%>').fadeOut(2000, function(){
$('.flash_messages').remove();
});
<% else %>
<% response.save %>
$('body').append('<%= j render partial: "shared/flash_messages"%>').fadeOut(2000, function(){
$('.flash_messages').remove();
});
<% end %>
<% else request.delete? %>
<% current_user.saveds.delete(#article) %>
$('body').append('<%= j render partial: "shared/flash_messages"%>').fadeOut(2000, function(){
$('.flash_messages').remove();
});
<% end %>

Simple_form is NOT showing any message when updating the form

I am using below simple_form in _form.html.erb which I am rendering in edit.html.erb, when editing the form, it do edit the fields but doesn't show any message that the form has been updated. I am very surprised why is this happening ? any help ?
<%= simple_form_for(#info, remote: true, :html => {class: 'form-horizontal'}) do |f| %>
<%= f.input :name %>
<%= f.input :phone %>
<%= f.input :email %>
<%= f.button :submit, class: 'btn btn-success' %>
<% end %>
Extracted from my project:
_flash_notices.html.erb
<div class="noticesWrapper">
<% flash.each do |name, msg| %>
<div class="alert alert-<%= name == :notice ? "success" : "error" %>">
<a class="close" data-dismiss="alert"><i class="icon-remove"></i></a>
<%= msg %>
</div>
<% end %>
</div>
! see the noticesWrapper element, as you'll need to render your notification inside of it.
application_controller.rb
after_filter :add_flash_to_header
def add_flash_to_header
# only run this in case it's an Ajax request.
return unless request.xhr?
# add different flashes to header
response.headers['X-Flash-Error'] = flash[:error] unless flash[:error].blank?
response.headers['X-Flash-Warning'] = flash[:warning] unless flash[:warning].blank?
response.headers['X-Flash-Notice'] = flash[:notice] unless flash[:notice].blank?
response.headers['X-Flash-Message'] = flash[:message] unless flash[:message].blank?
# make sure flash does not appear on the next page
flash.discard
end
update.js.erb
$('.noticesWrapper').html("<%= j(render partial: 'layouts/flash_notices') %>");
your_controller.rb
def update
#project = Project.find(params[:id])
if #project.update_attributes(params[:project])
flash.now[:notice] = "Project updated"
else
flash.now[:error] = "Project not updated"
end
end
end

How can I prevent the parameters hash from my flash being displayed along with the ERB output in the view template

I have implemented an application helper to dynamically provide the class of a flash message to the view for styling with Bootstrap. The setup works but along with the ERB, the actual parameters hash is being output to the view. I have look at all of my application code in the helpers and views and can't pinpoint the source. I've also looked at the output HTML and it was not indicative of the source problem. Below are the helpers and views as well as a snapshot of the troubled output result.
Troubled View Output
http://screencast.com/t/9KZHxjqm1Pq
--
# layouts/application.html.erb
...
</head>
<body>
<%= render "layouts/header" %>
<div class="container">
<% if flash.any? %>
<%= render 'shared/flash_messages' %>
<% end %>
<%= yield %>
...
--
# views/shared/_flash_messages.html.erb
<div>
<%= flash.each do |key, value| %>
<div class="<%= flash_class(key) %> fade in">
x
<%= "#{value}" %>
<% end %>
</div>
</div>
--
# helpers/application_helper.rb
module ApplicationHelper
def flash_class(level)
case level
when :notice then "alert alert-info"
when :success then "alert alert-success"
when :error then "alert alert-error"
when :alert then "alert alert-error"
end
end
end
It's because you are doing
<%= flash.each
So the result of each is displayed, as well as anything produced by the block. Change the <%= to <%

notices and errors on rails3

I read somewhere that rails 3 form helper does not have error messages embedded in it anymore. I am wondering how I am supposed to show flash messages when I set them up inside my controller or as an inline notice in redirect_to? How am I supposed to display them on my view? Is there helper for this?
For example if I have
def update
if #person.save
flash[:notice] = "Successfully saved!"
end
end
how do i show the notice on my view?
flash will still work as long as you display it in your layouts:
<div id="page">
<% if flash[:alert] %>
<p class="flash-error"><%= flash[:alert] %></p>
<% end %>
<% if flash[:notice] %>
<p class="flash-notice"><%= flash[:notice] %></p>
<% end %>
<%= yield %>
</div>
You can either display error messages manually or use the dynamic_form gem which gives you the old behavior.
You can still display flash messages in your view with this:
<%= flash[:notice] %>
But if you want to display for error messages:
#In your form
<%= form_for #foo do |f| %>
<%= render "shared/error_messages", :target => #foo %>
...
<% end %>
#shared/_error_messages.html.erb
<% if target.errors.any? %>
<div id="error_explanation">
<ul>
<% target.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>

Resources