Devise: Why doesn't my logout link work? - ruby-on-rails

the problem: In a nutshell, when I try to install a logout link to my app it fails to work. Here's as much context as I can think to put here (if you want anything else, please poke me)...
I've got this in a haml view:
= link_to("Logout", destroy_user_session_path, :method => :delete)
It generates this in the view:
Logout
I verified that in my config/initializers/devise.rb I have this setting uncommented and correct:
config.sign_out_via = :delete
I validated the following route:
destroy_user_session DELETE /users/sign_out(.:format) {:action=>"destroy", :controller=>"devise/sessions"}
I also have this bit of trickery in my routes.rb, and I suspect this is related to my issue:
devise_for :users, :controllers => {:sessions => "devise/sessions", :registrations => "users"}
resources :users
This last bit is because I want to manage (edit, create and delete) users in my own controller.
The error message I'm getting is as follows:
ActiveRecord::RecordNotFound in UsersController#show
Couldn't find User with ID=sign_out
Rails.root: /home/jaydel/projects/mbsquared-projects/Wilson-Goldrick
app/controllers/users_controller.rb:16:in `show'
In my server logs I see this for the request:
Started GET "/users/sign_out" for 127.0.0.1 at 2011-08-04 13:08:51 -0500
Processing by UsersController#show as HTML
Parameters: {"id"=>"sign_out"}
Anyone have any ideas?

The correct way to fix this, REST-wise, would be to change your logout links to use the DELETE method. It's a very easy fix, changing this:
link_to "Log out", destroy_user_session_path
to this:
link_to "Log out", destroy_user_session_path, :method => :delete

I had the same problem with rails 3.2 when I deleted from application.js this line:
//= require jquery_ujs
So, I think you have to insert this line in your application.js if you haven't it there.
PS. This behavior means that rails adapter for jquery doesn't function. So you should make sure if it is loaded in your html in browser. You should test it in development mode because you will have compressed js in production and it will be very difficult to find something there.

The problem lies in the fact that in your logs the signout request is a GET request.
Started GET "/users/sign_out"
But the signout route is a DELETE
destroy_user_session DELETE /users/sign_out(.:format)
The reason why you are getting the exception is that is it getting confused with one of the routes created by resources :users which would be something like
edit_user GET /users/(:id)(.:format) {:action=>"edit", :controller=>"users"}
Basically 'sign_out' is being mistaken as a id.
I'm not sure why the delete link is not going through as a DELETE request. Though changing
config.sign_out_via = :delete
to be :get might solve the problem.

You need both
link_to "Log out", destroy_user_session_path, method: :delete
&& these included in application.js
//= require jquery
//= require jquery_ujs
. Obviously, don't forget to add this to Gemfile if for some reason it is not there.
gem 'jquery-rails'

I've tried all the solutions mentioned here but the true solution to this issue is the following :
<%= link_to "Sign Out", destroy_user_session_path, 'data-turbo-method': :delete%>
It works if it doesn't just refresh or restart the server.

This is an old question but the accepted answer is not the proper way to solve this issue (although it is a good diagnosis of the problem).
When I ran into this today my routes file appeared as:
root :to => 'welcome#index'
resources :users
devise_for :users
As mentioned by Olives the resources statement is simply causing /users/anything to trip up. I simply needed to reverse the ordering of my routes...
root :to => 'welcome#index'
devise_for :users
resources :users

jQuery is required in order to perform the request with DELETE. Make sure you didn't drop it from your application.js.

Since the OP mentioned devise and this problem also happened to me, I just wanted to chime in. #Ross Allen had the correct answer when you don't want to use jQuery_ujs. Rails provides a couple of helpers to solve this without jQuery.
This is Ross's answer but using Devise's current_user model:
<%= form_for(current_user,
url: destroy_user_session_path, html: { method: :delete }) do |f| %>
<%= f.submit "Log out" %>
<% end %>
Or the more succinct button_to helper that creates a similar form:
<%= button_to "Log out", destroy_user_session_path, method: :delete %>

This is an old question, but I wanted a way that required no JavaScript. Rails enables "DELETE" like requests with a hidden input that sets method to delete. Use a real <form>, and let Rails generate the necessary hidden inputs:
<%= form_for(resource, as: resource_name,
url: destroy_user_session_path, html: { method: :delete }) do |f| %>
<%= f.submit "Log out" %>
<% end %>
the above generates something like:
<form accept-charset="UTF-8" action="/users/sign_out" method="post">
<div style="display:none">
<input name="utf8" type="hidden" value="✓">
<input name="_method" type="hidden" value="delete">
<input name="authenticity_token" type="hidden" value="1234">
</div>
<input name="commit" type="submit" value="Log out">
</form>

I've checked all this solutions, but no one has worked for me. Finally I found that in header I deleted two lines including application tags and csrf meta
So, If someone have this problem with no sollution at this point - check if you have in header of the page (HAML notation)
= javascript_include_tag 'application'
= csrf_meta_tags

I had to go about this in a different manner as my application.rb had:
<%= link_to "Sign out", destroy_user_session_path, :method => :delete %>
and was still failing. It turns out I needed to set config.serve_static_assets = true in /environment/development, test and production.rb. This link was what helped me figure it out.

You also have to check, is resources :users under devise_for :users and is the link method delete
link_to "Logout", destroy_user_session_path, method: :delete
if both are right, your logout button should work

I agree that it's more restful to use the http DELETE method, I like to create a simple endpoint to destroy a user session with a GET method.
by adding this to config/routes.rb
devise_scope :user do
get '/logout', :to => 'sessions#destroy'
end

If your are also having more than one jquery sources in your rails app you need to use the default one specified in the Gemfile
make sure in your Gemfile you have this
gem 'jquery-rails'
and in your assets you do not have any other JQuery source files.
in my case I had a second JQuery file other than the default as declared in the Gemfile so it caused conflicts.
if you previously had those source, be sure to precompile assets again if you had previously done so

If you're finding this problem in production and you're using the asset pipeline, you often need to:
rake assets:clobber in order to clear out your public assets. Then rake assets:precompile before committing and pushing your code (unless your push also precompiles, aka Heroku).

the reason may be in the wrong order connection bootstrap-sprockets
the correct order:
// app/assets/javascripts/application.js
...
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require bootstrap-sprockets
//= require_tree .

As mentioned by Tombart above, the answer for me was putting back the rails-ujs call in my application.js file.
//= require rails-ujs
//= require turbolinks
I had initially removed them to stop errors from having my scripts in the footer be re-evaluated. My workaround was to create a footer.js compile file with the resources I wanted in the footer.
//= require jquery-3.2.1.min
//= require jquery-ui-1.12.1.min
//= require materialize
//= require init
Then in my /initializers/assets.rb file adding a precompile
Rails.application.config.assets.precompile += %w( footer.js )
Then you can call the following in your layout/application.html.erb file.
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'footer' %>
I keep the application line in my header, and added my new "footer" call before the end of my body tag.

1) I feel u may need to install below gem, the request with method: :delete will work else it may go as get
https://github.com/rails/jquery-rails
2) Add this two below lines in application.js
//= require jquery
//= require jquery_ujs

Stop the server
yarn add "#rails/ujs"
yarn add turbolinks
yarn add #rails/activestorage
My application.js
import Rails from "#rails/ujs"
import Turbolinks from "turbolinks"
import * as ActiveStorage from "#rails/activestorage"
import "channels"
Rails.start()
Turbolinks.start()
ActiveStorage.start()
Start the server

Related

cloudinary-direct upload from browser not uploading

When I try to upload a file directly to Cloudinary nothing happens. The file name in the selected file field is deleted and no file is added to my Cloudinary accounts' Media Library.
This is my index.html.erb file
<%= cloudinary_js_config %>
<%= form_tag(cardset_cards_path(#cardset, #card), :method => :post) do %>
<%= cl_image_upload_tag(:image_id) %>
<%= submit_tag 'Submit' %>
<% end %>
My application.js file
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
// GO AFTER THE REQUIRES BELOW.
//
//= require jquery
//= require jquery_ujs
//= require_tree .
//= require cloudinary
I do have the downloaded cloudinary.yml file with api_key and api_secret...
I'm using Rails 4, I haven't set my config.assets.enabled = false, so I belive I am using Asset Pipeline by default.
I believe I'm following the example in Cloudinary, but my Cloudinary Account Media Library doesn't show any file uploaded. I've tried adding :html => {:multipart => true}, but the same things happens nothing. I've tried different things in the controller to get the returned id, but since nothing is happening, I think I'd just be happy to get a file into my Cloudinary Media Library.
-hoping to rise from the dirt to the Clouds

Why the destroy/delete link dees not work?

I am stuck at Delete/Destroy. Any help would be appreciated!
I am using Ruby 2.0.0 and Rails 3.2.6 on Mac 10.8.3 with Postgres.
This is the delete link which supposed to work:
<%= link_to 'Destroy', #product, method: :delete, data: { confirm: 'Are you sure?' } %>
But when I click on the Destroy link it directs me to the user's profile. I don't get any confirmation window and no action is done (delete). It seems it is just stayed at the same page. I am using Firefox but in IE and Chrome are the same.
This is what I have:
the gem "jquery-rails" is installed
applications.js (from app/assets/javascripts) has these lines:
//= require jquery
//= require jquery_ujs
//= require_tree .
application.html.erb (from app/views/layouts) has these lines:
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
In view source I see:
<script src="/assets/application.js?body=1" type="text/javascript"></script>
<meta content="authenticity_token" name="csrf-param" />
<meta content="MVlJi+WJE1cwWoHnBrpRWIa13gqio0iPT3IL6kpQYdE=" name="csrf-token" />
in products_controllers.rb (from app/controllers) I have:
def destroy
#product = Product.where(:id => params[:id]).first
#product.destroy
respond_to do |format|
format.html { redirect_to products_url }
format.json { head :no_content}
end
end
in routes.rb (from config) I have:
resources :products
What is wrong with that Destroy link?
On the same RoR project the Edit link works fine.
So, why the link doesn't work? Is it a Javascript problem or some other problem which I am not seeing?
And here is the server's log: (It seems the "delete" action does not been executed)
Started GET "/products/9" for 127.0.0.1 at 2013-08-01 20:01:08 -0500
Processing by ProductsController#show as HTML
Parameters: {"id"=>"9"}
Product Load (0.1ms) SELECT "products".* FROM "products" WHERE "products"."id" = 9 LIMIT 1
Rendered products/show.html.erb within layouts/application (0.5ms)
Completed 200 OK in 27ms (Views: 25.8ms | ActiveRecord: 0.1ms)
One helpful way to handle path issues with Rails is to type "rake routes" in your console, in order to have a list of all the paths available to play with your ressources.
By declaring "resources :products" in your routes.rb file, "rake routes" will provide a list of Prefix/Verb/URI Pattern/Controller#Action for this particular resource. You will have something like:
Prefix Verb URI Pattern
product GET /product/:id(.:format) product#show
PATCH /product/:id(.:format) product#update
DELETE /product/:id(.:format) product#destroy
Take the word of the prefix column (product), add _path to this word (product_path), use the correct method (DELETE), pass the ids as parameters (in this case, you can just do product_path(#product)), and you're done. You will have :
<%= link_to "Delete", product_path(#product), method: :delete, data: { confirm: "Are you sure?" } %>
Perhaps (I'm just guessing, but one day I ran into a similar problem) if you design catalog or shop with a shopping cart based on the book Agile Web Development with Rails, the product model may contain a filter before_destroy :ensure_not_referenced_by_any_line_item that prevents the product from destroy in case if product listed in LineItems. If this is your case, you can clear list of LineItems in the ProductsController before destroying the product. Otherwise sorry.

Rails 3.2.1 simple JQuery ajax example doesn't work

I'm just trying to learn a bit of jQuery with Rails at the moment. I'm following the example here:
Ideas on simple 'Hello World' Rails-Ajax Example?
My view looks like this:
/views/main/ajax_msg.erb
<div id="div_msg">
<%= link_to "Wow",
{:controller=>"main" , :action=>'ajax_msg' , :id=>'1'},
:remote => true,
:class => 'link1',
:update => "div_hello",
:id => 'link1'
%>
</div>
<div id="div_hello">
</div>
My controller looks like this:
/controllers/main_controller.rb
def ajax_msg
#msg1 = "Buenos Dias!"
respond_to do|format|
format.html
format.js
format.json
end
end
My javascript file looks like this:
/views/main/ajax_msg.js
jQuery('#div_hello').html("<%= #msg1 %>");
My /views/layouts/application.html.erb begins like this...
<!DOCTYPE html>
<html>
<head>
<title>SomeApp</title>
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
</head>
My application.js contains...
//= require jquery
//= require jquery-ui
//= require jquery_ujs
//= require_tree .
My console log shows me this:
Started GET "/main/ajax_msg?id=1" for 127.0.0.1 at 2013-07-09 21:44:57 +0100
Processing by MainController#ajax_msg as JS
Parameters: {"id"=>"1"}
Rendered main/ajax_msg.js within layouts/application (1.0ms)
Completed 200 OK in 19ms (Views: 19.0ms | ActiveRecord: 0.0ms)
I have tried many different combos by looking at other people's problems on related issues but nothing seems to work. I have tried the following:
- using $ instead of jQuery in the javascript file
- putting the javascript in application.js
- switching the order between stylesheet_link_tag and javascript_include_tag
Am I missing something quite basic here?
Thanks.
Try renaming /views/main/ajax_msg.js to /views/main/ajax_msg.js.erb so that file can handle embedded Ruby?
For debugging and to make sure it's rendering embedded ruby you can just try doing any other string in there:
jQuery('#div_hello').html("<%= puts 'blah' %>");
I think that is the problem.
1) File should be called js.erb, because, obvioulsy, if you are using Ruby variable inside, it should be extended ruby
2) From Jquery API:
Get the HTML contents of the first element in the set of matched elements or set the HTML contents of every matched element.
That means, that string should be wrapped with tags, if you are trying to set page element.
Try:
$('#div_hello').text("<%= #msg1 %>")
Also, if this doesn't work, try to escape javascript:
$('#div_hello').text("<%= j #msg1 %>")

gmap4rails in ActiveAdmin: maps does not appear

In try to use gmaps4rails in my ActiveAdmin / Rails app. To do so, I have added the following in my Gemfile:
gem 'gmaps4rails'
and ran a "bundle". I updated the 'show' method in app/admin/device.rb file with:
show do
attributes_table do
row :name
end
# Get device location
#markers = Location.all.to_gmaps4rails
div do
render "map"
end
end
In the app/views/admin/devices/_map.html.erb I have the following code:
<%= stylesheet_link_tag 'gmaps4rails' %>
<%= gmaps4rails(#markers) %>
<%= yield :scripts %>
In app/assets/javascripts/application.js:
//= require gmaps4rails/gmaps4rails.googlemaps
//= require gmaps4rails/gmaps4rails.base
//= require jquery
//= require jquery_ujs
//= require_tree .
And in my app/models/location.rb:
class Location < ActiveRecord::Base
acts_as_gmappable
attr_accessible :latitude, :longitude
def gmaps4rails_address
"#{self.latitude}, #{self.longitude}"
end
def location
[:latitude, :longitude]
end
end
When I go on the show page of a device, the map does not shows up (all blank). Is there any configuration I missed ?
UPDATE
I have checked with chrome developer tools and noticed the following error:
Uncaught SyntaxError: Unexpected token ;
that make reference to the line:
Gmaps.map.markers = ;
Fix with the following:
div do
markers = Location.all.to_gmaps4rails
render "map", { :markers => markers }
end
and :
<%= stylesheet_link_tag 'gmaps4rails' %>
<%= gmaps({
"map_options" => { "zoom" => 2, "auto_adjust" => false},
"markers" => { "data" => markers }
})
%>
<%= yield :scripts %>
You have to load the Javascript files in the /config/initializers/active_admin.rb; search for the section:
# To load a javascript file:
# config.register_javascript 'my_javascript.js'
Also, I think you should add the CSS files (if is not appearing) into the same file.
Remember that ActiveAdmin manages its own Javascript file, named active_admin.js; you can try loading the Javascript files in this JS; some time ago I had a similar problem and I only was able to solve it adding the files in the initializer.

Why Ajax renders 2 views in rails 3.1 app

When entering log in our rails 3.1 app, ajax is used to render the input screen below. Here is the link for log:
<%= link_to 'Log', new_part_out_log_path(#part, :format => :js), :remote => true, :id => 'new_log_link' %>
And the new.js.erb as this:
$("<%= escape_javascript render(:file => 'out_logs/new.html.erb') %>").insertAfter('#new_log_link');
$('#new_log_link').hide();
$('#close').hide();
the problem is that after clicking 'Log', instead of one view, 2 identical views of out_logs/new.html.erb were rendered. What may be wrong with our code? thank so much.
The problem is related to upgrade to ruby 1.9.3 which causes webrick server (for development) warning message and also rendering the .js.erb file twice on screen. The twice rendering problem disappears on our production server which is running nginx. The following link may help to understand the problem:
http://theresa.multimediatechnology.at/webrick-warnings-in-ruby-1-9-3/
What does "WARN Could not determine content-length of response body." mean and how to I get rid of it?

Resources