Best practice method of displaying flash messages - ruby-on-rails

I'm wondering what's the best practice for displaying flash messages. The two main ways I've seen are using something like this scaffold generated code
<p id="notice"><%= notice %></p>
or placing code like this in your application header.
<% if !flash.empty? %>
<div id="flash">
<% flash.keys.each do |k| %>
<div class="<%= k %>">
<%= flash[k] %>
</div>
<% end %>
</div>
<% end %>
It appears to me that the first method adds more flexibility while the latter improves code readability and eliminates redundancy. Is there a method most rails developers prefer? As a side question how does scaffolding implement notice? Is it just a helper that accesses the flash hash? Why go through the trouble of using the helper when you can directly use the flash hash? Thanks

I'm doing it this way:
<% flash.each do |key, value| %>
<%= content_tag :div, value, class: "flash #{key}" %>
<% end %>

Calling a partial keeps your application.html.erb even cleaner..
<%= render 'shared/flash_messages' if !flash.empty? %>
.. and in the partial do something like what #zolter mentioned:
<div id="flash_messages">
<% flash.each do |key, value| %>
<%= content_tag(:div, value, :class => "flash #{key}") %>
<% end %>
</div>

Why not put the second method on a helper function so it doesn't affect code readability on layouts?

<% if flash[:notice] %>
<div class="notification is-primary global-notification">
<p class="notice"><%= notice %></p>
</div>
<% end %>
<% if flash[:alert] %>
<div class="notification is-danger global-notification">
<p class="alert"><%= alert %></p>
</div>
<% end %>

Related

Using Loop Variable to Set the id Attribute

I have the following code:
<% #electives.each do |elective| %>
<div>
</div>
<% end %>
I would like to set the id of the div to elective.name, but I don't know how to do it, or whether this works:
<% #electives.each do |elective| %>
<div id="elective.name">
</div>
<% end %>
Is it possible to do this in Rails?
Thanks.
You can use <%= ruby variable %> block within erb file to add ruby values within your pages
<div id="<%= elective.name %>">
As an alternative solution, you can use the rails tag helper
<% #electives.each do |elective| %>
<%= tag.div id: elective.name do %>
...
<% end %>
<% end %>

How to group and dry common view code in Rails

I have two models Episode and Playlist with the following two views:
For Episode:
<div class="name">
<%= link_to episode.name, episode_path(episode) %>
</div>
<div class="description">
<%= link_to episode.description episode_path(episode) %>
</div>
For Playlist:
<div class="name">
<%= link_to playlist.name, playlist_path(playlist) %>
</div>
<div class="description">
<span>Some special span</span>
<%= raw(playlist.description) %>
</div>
The common things between this two views are the
<div class="name">. <div class="description">
but the content of this two divss is different for each view.
Question: How could I extract this two common divs into another view, called _section?
What have I tried:
Cells -> they give me a nice view model with properties, but I could not find a way to added additional HTML elements between the places where the properties will be put.
Yield and Content_for-> I have tried to create a separate _section layout with:
_section.html.erb
<div class="name">
<%= yield :name %>
</div>
<div class="description">
<%= yield :description %>
</div>
and then two views. The Episode view will render the following
<% render layout: "section" do %>
<% content_for :name do %>
<%= link_to episode.name, episode_path(episode) %>
<% end %>
<% content_for :description do %>
<%= link_to episode.description episode_path(episode) %>
<% end %>
<% end %>
This kind of works until you get to caching (they said content_for does not work with caching and I need to cache this) and the other problem I had was that you should include an additional empty not named yield.
I ended up with moving all the logic for playlist and episode views into a single view - called section that basically does the following:
<div class="name">
<%= link_to object.name, polymorphic_path(object) %>
</div>
<div class="description">
<% if is_episode? %>
<h1>Some special h1 for episode</h1>
<% elsif is_playlist? %>
<h2>Some special other html for playlist for episode</h2>
<% end %>
<%= raw(playlist.description) %>
</div>
Wow those "ifs" are ugly. I am not sure if I understood the problem correctly, but it is surprising I could not find a cleaner solution.

How to use the default layout for nested controller?

Pretty new to rails and I was building my routes to get a nested controller like this:
resources :companies do
member do
get 'operating_hour'
end
resources :services do
member do
get 'services'
end
end
end
Now, my layout for my applications is like this:
<body>
<%= render 'layouts/header' %>
<div class="container">
<% flash.each do |key, value| %>
<div class="alert alert-<%= key %>"><%= value %></div>
<% end %>
<% if main_side_view? %>
<%= render 'layouts/main_side' %>
<% elsif company_side_view %>
<%= render 'layouts/company_side' %>
<% else %>
<h1><%= yield(:title) %></h1>
<%= yield %>
<% end %>
<%= render 'layouts/footer' %>
</div>
All is working fine with my layout except all that is generated by the nested ('service') controller. When I go to a link of the nested controller my layout is not there!
Any help?
I think you do it in a wrong way. You should create several layouts :
First, layouts/application.html.erb
<%= render 'layouts/header' %>
<div class="container">
<% flash.each do |key, value| %>
<div class="alert alert-<%= key %>"><%= value %></div>
<% end %>
<h1><%= yield(:title) %></h1>
<%= yield %>
<%= render 'layouts/footer' %>
</div>
Second, layouts/companies.html.erb
<%= render 'layouts/header' %>
<div class="container">
<% flash.each do |key, value| %>
<div class="alert alert-<%= key %>"><%= value %></div>
<% end %>
Your code for companies
</div>
See the guide : http://guides.rubyonrails.org/layouts_and_rendering.html#using-nested-layouts
You can create a shared view for flash messages.

How do I change notice & alert's class?

I'm trying to adjust the standard application template in Rails to insert a class around the notice and alert messages, but I can't seem to find an elegant way of doing it.
At present, I have the scaffold:
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
I want it to only show the surrounding tags if a notice or alert is present.
Use an if statement.
<% if notice %>
<p class="notice"><%= notice %></p>
<% end %>
<% flash.each do |name, msg| %>
<%= content_tag :div, :id => "flash_#{name}", :class => "my_class" do %>
<%= msg %>
<% end %>
<% end %>
Define styling for the .my_class
Wrap the parts in if like this:
<% if alert %>
<p class="alert"><%= alert %></p>
<% end %>
You can also use unless if you like

Rails: How to name and create unique divs within a loop?

I have a view with a div that is looped many times. Each of the created divs need to have a unique ID so I can access them specifically (at the moment, all my divs have the same ID specified in html so whenever I try to access a specific div it just finds the first one).
This is the version that I currently have (multiple 'rowBox'es are not discernible).
<% #customers.each do |customer| %>
<div id="customer" class="rowBox">
...
</div>
<% end %>
I would like to be able to do something like:
<% #customers.each do |customer| %>
<div id="box<%=customer.id%>">
...
</div>
<% end %>
This doesn't seem to work. Any ideas on how to accomplish this?
Rails has some handy helpers for exactly this.
<% #customers.each do |customer| %>
<%= div_for customer, :class => "rowBox" do %>
...
...
<% end %>
<% end %>
This will produce e.g.:
<div id="customer_1" class="customer rowBox">
...
</div>
<div id="customer_2" class="customer rowBox">
...
</div>
......
<% #customers.each do |customer| %>
<div id=<%= "box#{customer.id}" -%>>
...
</div>
<% end %>
Sorry for earlier omission. This should work.

Resources