How to render error messages in views in Rails? - ruby-on-rails

I have created a cart in the products view and want to display an error message
views/products/index.html.erb
<% if #order.errors.any? %>
<div class="error error-success note-shadow">
<% #order.errors.full_messages.each do |msg| %>
<p><%= msg %></p>
<% end %>
</div>
<% end %>
controllers/orders_controller.rb
def create
#order = Order.new(params_slip)
respond_to do |format|
if #order.save
format.html {
redirect_to :back,
notice: 'Order was successfully placed.'
}
else
format.html { redirect_to :back }
end
end
end
I am using the above method trying to display the error messages, but it didn't work out. I supposed that is because my create action is in orders_controller, and I couldn't add the error message to the products view?

The root cause is the #order instance variable is not being carried through the redirection process, so that's the reason you don't see any error messages.
You can put the error messages into flash container
if #order.save
[do something]
else
flash[:order_errors] = #order.errors.full_messages
redirect_to :back
end
<% if flash[:order_error] %>
[display it here]
<% end %>

I'm not sure why you put your form in index.html.erb. You'd better put your form in your new.html.erb.
Try to change:
format.html { redirect_to :back }
Into:
render "index"
I hope this helps you

Related

Ruby on Rails: controller action cannot display notice alert

I found this weird problem in my app. When user is trying to edit the article and do it wrong, e.g not passing model validations then my update action do not send flash message to the view. Even if it shoud do it:
def update
respond_to do |format|
if #article.update(article_params)
format.html do
redirect_to article_path,
notice: 'Article has been updated'
end
else
format.html do
render :edit,
notice: "Article couldn't be updated. Please try again" //this is what should be send to the view
end
end
end
Flash render in application.html.erb:
<% flash.each do |key, value| %>
<div class="alert alert-<%= key %>">
×
<ul>
<li>
<%= value %>
</li>
</ul>
</div>
<% end %>
In this case, when I type <%= flash.inspect %> I also get an empty hash:
#<ActionDispatch::Flash::FlashHash:0x00007fa5c05fcd60 #discard=#<Set: {}>, #flashes={}, #now=nil>
What make this situtation weird is that my flash alerts works fine in any other cases. E.g. when update action passes validations 'Article has been updated' message is displayed. Only in this case it cannot be done. How can I fix it?
Use flash.now instead
....
else
format.html do
flash.now[:alert] = "Article couldn't be updated. Please try again"
render :edit
end
end
flash.now

Flash messages only show after redirecting twice

flash[:errors] does not show after redirect_to in create method. But if I send another invalid form it shows up on the second and all following redirects. The same goes for flash[:success] when there are no errors.
I've tried using flash.keep in both this and the route I am redirecting to, and the views work since the messages do appear after multiple redirects. I'm wondering if it is because the redirects are to routes that render too?
In Controller:
def create
user = User.create(user_params)
if user.errors.any?
flash[:errors] = user.errors.full_messages
redirect_back(fallback_location: root_path)
else
flash[:success] = "USER SUCCESSFULLY CREATED"
redirect_to root_path
end
end
In Views:
<% if flash[:errors] %>
<% flash[:errors].each do |error| %>
<p style="color:red;"><%= error %></p>
<% end %>
<% end %>
AND:
<% if flash[:success] %>
<p style="color: red;"><%= flash[:success] %></p>
<% end %>
No flash messages are shown after the first redirect. After or more redirects, the flash messages are shown

Rails remote: true undefined method in view

I have a Rails 5.0.2 app and I've managed to implement a user following system using the acts_as_follower gem. Everything works nicely, however, I'm running into some trouble adding ajax.
I'm getting the following error when clicking 'follow'
NoMethodError at /7/follow
==========================
> undefined method `followed_by?' for nil:NilClass
I have the following
users_controller.rb
def follow
user = User.find(params[:id])
current_user.follow(user)
respond_to do |format|
format.html { redirect_to user}
format.js
end
end
show.html.erb
...
<div id="follow">
<%= render partial: "users/following", locals: {user: #user} %>
</div>
...
_following.html.erb
<% if !#user.followed_by?(current_user) %>
<%= link_to follow_user_path(#user.id), remote: true do %>
<h4><span class="label label-primary">Follow</span></h4>
<% end %>
<% else %>
<%= link_to unfollow_user_path(#user.id) do %>
<h4><span class="label label-primary">Unfollow</span></h4>
<% end %>
<% end %>
I understand that I have no #user in my partial after creating the record and I can't work out how to pass it back in to the partial. Any help would be appreciated.
Silly me.
In the follow method I had this:
def follow
user = User.find(params[:id])
current_user.follow(user)
respond_to do |format|
format.html { redirect_to user}
format.js
end
end
but should have been
def follow
#user = User.find(params[:id])
current_user.follow(#user)
respond_to do |format|
format.html { redirect_to #user}
format.js
end
end
#user rather than user
your problem here is that in your controller you have user, without the "#" user is a variable that exist just in your controller method, and #user is an instance variable that can be accessed on the view.
So if you plan to use this on the view, you need to add "#" to the variable.

Nested Resource Sad Path Renders blank comment

I have a comment resource nested in a post resource.
def create
#post = Post.find(params[:post_id])
#comment = #post.comments.build(params[:comment])
#comment.ip = request.remote_ip
if #comment.save
redirect_to post_path(#post, notice: "Comment was successfully created")
else
flash[:alert] = "Comment could not be created"
render 'posts/show'
end
end
This all works well enough, but I have a nag item in that when the posts/show page with the comment form re-renders, it shows the comment that didn't pass validation inline. I'd like to know the correct way to do this, short of performing some logic in the view layer to not display a comment that isn't saved.
I ended up solving it in the view, because I couldn't find any other solution
<% #post.comments.each do |c| %>
<% unless c.new_record? %>
<strong><%= "#{c.name} wrote: " %></strong><br />
<blockquote><%= c.body %></blockquote>
<% end %>
<% end %>

Issue with flash messages in ruby 1.9.3 and rails 3.2.2

I have a issue with flash message in my application. Actually in my application i have used the devise for users authentication and my application with ruby 1.9.3 and rails 3.2.2.
When an user is login, logout and sign up for new account the devise flash[:notice] is working fine.
In Rails flash[:notice] and flash[:alert] are the default flash messages.
The flash messages are display only once when page reload or when the user negative from one page to other page
The issue is when user is login the devise flash[:notice] is displaying but when i reload the page the flash[:notice] is displaying, but in rails the flash[:notice] will display only once
Actually the issue is when i try to create a new post i have redirect to the show page and i have write helper method for flash message this method i have call from the application layout for displaying the flash messages.
In controller create method
def create
#asset = Asset.new(params[:asset])
#asset.user_id = current_user.id
respond_to do |format|
if #asset.save
format.html { redirect_to #asset, alert: 'Asset was successfully created.' }
format.json { render json: #asset, status: :created, location: #asset }
else
format.html { render action: "new" }
format.json { render json: #asset.errors, status: :unprocessable_entity }
end
end
end
The Helper method for displaying flash messages
FLASH_TYPES = [:error, :warning, :success, :message,:notice,:alert]
def display_flash(type = nil)
html = ""
if type.nil?
FLASH_TYPES.each { |name| html << display_flash(name) }
else
return flash[type].blank? ? "" : "<div class=\"#{type}\"><p>#{flash[type]}</p> </div>"
end
html.html_safe
end
i have call this method form the application layout
= display_flash
I have tried with the flash[:alert], flash[:error],flash[:message] but no message display on the view page and i have tried with gem called flash_message this also displays only the
flash[:notice]
Please help me to solution this issue
Hy i am using using this approach to show flash message.First i make partial
_flash.html.erb in shared.The code of this partial
<% [:alert, :notice, :error].select { |type| !flash[type].blank? }.each do |type| %>
<p>
<% if flash[:notice] %>
<div class="alert-message error">
<h2 style="color: #ffffff;">Notice:</h2> <br/>
<%= flash[type] %>
</div>
<% elsif flash[:error] %>
<div class="alert-message error">
<h2 style="color: #ffffff;">Errors</h2> <br/>
<% flash[:error].each_with_index do |error, index| %>
<%= index+1 %>. <%= error %> <br/>
<% end %>
</div>
<% end %>
</p>
<% end %>
and i call it in application layout like this
<div id="flash">
<%= render :partial => 'shared/flash', :object => flash %>
</div>
And in controller use notice,alert like this
flash[:notice] = 'Admin was successfully created.'
flash[:alert] = 'Admin was successfully created.'
But for showing errors i use array because it may be more than one.Like this
def create
#user = User.new(params[:user])
#user.is_activated = true
# #user.skip_confirmation!
if #user.save
role = Role.find_by_name("admin")
RoleUser.create!(:user => #user, :role => role)
redirect_to :controller => '/administrator', :action => 'new'
flash[:notice] = 'Admin was successfully created.'
else
flash[:error]=[]
#user.errors.full_messages.each do |error|
flash[:error] << error
end
render :action => "new"
end
end
add this line in application.js
setTimeout("$('#flash').html(' ');", 10000);
Use it and enjoy!!!!!!!!!!!!!!

Resources