notices and errors on rails3 - ruby-on-rails

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 %>

Related

Ruby on Rails Flash Notice Not working properly

Flash notice is not working. I am using rails 5.1.
My code is like this:
def message
redirect_to users_path, notice: "Message"
end
<% if flash.present? %>
<% flash.each do |k, v| %>
<p class="abc" id="a"><%= v %></p>
<% end %>
<% else %>
<p class="a" id="b"></p>
<% end %>
Flash Message is coming few times and few times it's not coming, It's going in else block.
So, for this I have fixed by using flash.keep in users index controller. But Now in every page whenever I am redirecting,that flash message is coming.
You can try as:
def message
flash[:notice] = 'Message'
redirect_to users_path
end
And in your view:
<% if flash[:notice].present? %>
<% flash.each do |k, v| %>
<p class="abc" id="a"><%= v %></p>
<% end %>
<% else %>
<p class="a" id="b"></p>
<% end %>
Hope it can solve your problem.
I think the flash hash is always present. You can check if it's empty instead https://api.rubyonrails.org/classes/ActionDispatch/Flash/FlashHash.html#method-i-empty-3F
<% if flash.empty? %>
<p class="a" id="b"></p>
<% else %>
<% flash.each do |k, v| %>
<p class="abc" id="a"><%= v %></p>
<% end %>
<% end %>

Allow unauthenticated users to access views that utilize current_user

I have lots of views that have elements that check if the current user isn't the same user that's being viewed, etc. For example, on the user show page there is a button that allows a user to follow another user, which doesn't appear if the user is looking at their own profile.
<% if current_user != #user %>
<div id="follow_form">
<% if current_user.following?(#user) %>
<%= render 'users/unfollow' %>
<% else %>
<%= render 'users/follow' %>
<% end %>
</div>
<% end %>
The problem arises that if you're not logged in, rails throws an error.
undefined method `id' for nil:NilClass
<% if current_user.id == #user.id %>
<%= link_to "Edit Profile", edit_user_registration_path(#user) %>
<% else %>
<%= link_to 'message', new_message_path(receiver_id: #user.id) %>
...
I don't want to have to force people to log in or sign up to view index or show pages. How can I get around this?
You should try that:
<% if user_signed_in? %>
<% if current_user != #user %>
<div id="follow_form">
<% if current_user.following?(#user) %>
<%= render 'users/unfollow' %>
<% else %>
<%= render 'users/follow' %>
<% end %>
</div>
<% end %>
<% 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 %>

Control Structure in Rails Partial

I'm building a Rails app up from the Sample App featured in Michael Hartl's book. In order to display error messages on user signup, I'm using a partial in the shared directory - app/views/shared/_error_messages.html.erb:
<%if #fact %>
<% #data = #fact %>
<% elsif #user %>
<% #data = #user %>
<% end %>
<% if #data.errors.any? %>
<div id="error_explanation">
<div class="alert alert-error">
The form contains <%= pluralize(#data.errors.count, "error") %>.
</div>
<ul>
<% #data.errors.full_messages.each do |msg| %>
<li>* <%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
Originally, this partial just started with something like:
<% if #user.errors.any? %>
However, since I've decided to re-use this partial to show errors on other pages, I'm having to use different objects (#user, #fact) depending on which page I'm using it on. This is easily solved by adding that IF statement at the top,
<%if #fact %>
<% #data = #fact %>
<% elsif #user %>
<% #data = #user %>
<% end %>
-but this feels icky. Is there a controller somewhere I should be putting this kind of logic for shared partials?
You can pass local variables to partial instead:
<% if object.errors.any? %>
<div id="error_explanation">
<div class="alert alert-error">
The form contains <%= pluralize(object.errors.count, "error") %>.
</div>
<ul>
<% object.errors.full_messages.each do |msg| %>
<li>* <%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
And in your template, for example:
<%= render 'shared/error_messages', object: #user %>
Marek's answer is probably the best. However, here is an alternative which though not scalable, is closer to what you have done.
Just replace:
<%if #fact %>
<% #data = #fact %>
<% elsif #user %>
<% #data = #user %>
<% end %>
with:
<% #data = #fact||#user %>
You could use render to point to the partial from your controllers for users and fact. Check out the API documentation on rendering partials.

RAILS HABTM checkboxes don't update

I am trying to realize HABTM checkboxes following this tutorial:
http://www.justinball.com/2008/07/03/checkbox-list-in-ruby-on-rails-using-habtm/
While everything seems to work nicely the updates are not saved to my database.
My controller looks like the following:
class UserrolesController < ApplicationController
before_action :set_userrole
def edit
#projects=Project.all
end
def update
params[:userrole][:project_ids] ||= []
#userrole = Userrole.find(params[:id])
if #userrole.update_attributes(userrole_params)
flash[:notice] = "Settings have been saved."
redirect_to edit_userrole_url(#userrole)
else
flash.now[:error] = #userrole.errors
setup_form_values
respond_to do |format|
format.html { render :action => :edit}
end
end
end
private
def set_userrole
#userrole = Userrole.find(params[:id])
end
def userrole_params
params.require(:userrole).permit(:name, :project_ids)
end
end
My _form.html.erb like this:
<%= form_for(#userrole) do |f| %>
<% if #userrole.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#userrole.errors.count, "error") %> prohibited this person from being saved:</h2>
<ul>
<% #userrole.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="center">
<div class="field">
<%= f.label :Name %>
<%= f.text_field :name %>
</div>
<ul class="checkbox-list">
<% #projects.each do |project| -%>
<li><%= check_box_tag "userrole[project_ids][]", project.id, userrole_edits_project?(project) -%> <%= project.name -%></li>
<% end -%>
</ul>
<div class="actions">
<%= f.submit "Speichern", class: "btn btn-primary" %>
</div>
</div>
<% end %>
So I did everything like in the tutorial, the :name is saved without any problems, but the ids are not saved to the database. There is no error message. Does anybody has an idea what might go wrong? Maybe some missing permission somewhere?
So finally I found a work around for this problem.
I forced the update of project_ids by adding the following line in def update:
#userrole.project_ids=params[:userrole][:project_ids]

Resources