Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 268
Sravan Avatar asked Dec 18 '15 09:12

Sravan


2 Answers

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
like image 131
David Runger Avatar answered Oct 20 '22 20:10

David Runger


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

like image 42
Richard Peck Avatar answered Oct 20 '22 19:10

Richard Peck