0

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" ?

Sahil
  • 3,338
  • 1
  • 21
  • 43
Timmy Von Heiss
  • 2,160
  • 17
  • 39
  • 1
    One way to do is create a js function which temporarily adds a div(the one which you have in `application.html.erb`) and then fades it away. Call that js function in **saved.js.erb**, have a type field in that function by which you add a class success or danger for different types of flash messages. This helps because you use this function globally across your website. – Sahil Nov 15 '16 at 18:39

2 Answers2

1

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 %>
Community
  • 1
  • 1
Sahil
  • 3,338
  • 1
  • 21
  • 43
1

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.

mr_sudaca
  • 1,156
  • 7
  • 9