Is there a way to alert/popup in a rails controller method without rendering any other js file

15,553

Solution 1

Try this in your else block:

render html: "<script>alert('No users!')</script>".html_safe

Note that if you want to include the <script> tag in a proper HTML layout (with a <head> tag, etc.), you'll need to explicitly specify a layout:

render(
  html: "<script>alert('No users!')</script>".html_safe,
  layout: 'application'
)

Edit:

Here's a little more code:

app/controllers/users_controller.rb:

class UsersController < ApplicationController
  def delete_users
    users = User.active.where(:id=>params[:users])
    array = []
    users.each do |user|
      if user.active?
        array << user
      end
    end
    if (array.count > 0)
      user.update_attributes(:status => "inactive")
    else
      render(
        html: "<script>alert('No users!')</script>".html_safe,
        layout: 'application'
      )
    end
  end
end

user.rb:

class User < ActiveRecord::Base
  # for the sake of example, simply have User.active return no users
  def self.active
    none
  end
end

config/routes.rb:

Rails.application.routes.draw do
  # simply visit localhost:3000 to hit this action
  root 'users#delete_users'
end

Solution 2

You can't invoke a dialogue / popup box directly from the controller; it has to form part of a response to your browser.


Because Rails is built on the HTTP stateless protocol, each request has to be met with a response. Unlike TCP or Web Sockets, HTTP only has the capacity to receive ad-hoc responses:

HTTP functions as a request-response protocol in the client-server computing model. A web browser, for example, may be the client and an application running on a computer hosting a web site may be the server. The client submits an HTTP request message to the server. The server, which provides resources such as HTML files and other content, or performs other functions on behalf of the client, returns a response message to the client. The response contains completion status information about the request and may also contain requested content in its message body.

This means that you have deliver any front-end changes to your browser before they'll take effect (IE you can't just say "load dialogue" because it won't be sent to the browser):

#app/controllers/your_controller.rb
class YourController < ApplicationController
   respond_to :js, only: :destroy_users #-> this will invoke destroy_users.js.erb

   def destroy_users
      @users = User.active.where(id: params[:users]).count
      if @users.count > 0
         @users.update_all(status: "inactive")
      else
         @message = "No users......"
      end
   end
end

#app/views/your_controller/destroy_users.js.erb
<% if @message %>
  alert(<%=j @message %>);
<% end %>

The above code invokes the js.erb response which can be invoked using respond_to

Share:
15,553
Sravan
Author by

Sravan

Hai, This is Sravan. I am a Ruby On Rails(R.O.R) and a Mean-Stack developer and I love coding and technology.

Updated on July 05, 2022

Comments

  • Sravan
    Sravan almost 2 years
    def delete_users
      users = User.active.where(:id=>params[:users])
      users.each do |user|
        array = []
        if user.active?
          array << user
        end
      end
      if (array.count > 0)
        user.update_attributes(:status => "inactive")
      else
        "I want an alert/popup here saying no users, when 'delete_users' is called and the condition comes here."
        ........ do other stuff ......
      end  
    
    end  
    

    end

    In a controller, I have this method, the ajax call will be made to get to this method and when the condition comes to else, I need an alert/popup saying no users are there to delete, then I can update some other thing.

    Thanks in advance.

  • Sravan
    Sravan over 8 years
    Can't we even display the flash messages in the middle of a controller Action?
  • Richard Peck
    Richard Peck over 8 years
    Definitely not. You have to send the response back to the server
  • Sravan
    Sravan over 8 years
    tried but didn't work. I think it should be rendered back to a template to get it work.
  • David Runger
    David Runger over 8 years
    What doesn't work? This works for me. I added some additional code in my answer.