Devise destroy_user_session_path doesn't work - ruby-on-rails

In my ruby on rails application I've a problem for the user logout with devise
I've this navbar:
<% if current_user %>
<nav class="top-bar" data-topbar role="navigation">
<ul class="title-area">
<li class="name">
<h1><%= link_to 'Prova CMS', articles_path %></h1>
</li>
<li class="toggle-topbar menu-icon"></li>
</ul>
<section class="top-bar-section">
<ul class="right">
<li><%=link_to 'Gestisci Articoli', articles_path %></li>
<li><%=link_to 'Gestisci Categorie', categories_path %></li>
<li class="has-dropdown">
<%= current_user.email %>
<ul class="dropdown">
<li><%= link_to "Logout", destroy_user_session_path, :method => :delete %></li>
</ul>
</li>
</ul>
<% if current_page?(articles_path) %>
<ul class="left">
<div class="large-12 columns">
<%= form_tag articles_path, :id => "articles_search" , method: 'get' do %>
<%= text_field_tag :search, params[:search], :placeholder => "Cerca per titolo"%>
<% end %>
</div>
</ul>
<% end %>
</section>
</nav>
<% else %>
<nav class="top-bar" data-topbar role="navigation">
<ul class="title-area">
<li class="name">
<h1><%= link_to 'Prova CMS', root_path %></h1>
</li>
<li class="toggle-topbar menu-icon"></li>
</ul>
<section class="top-bar-section">
<ul class="right">
<li><%= link_to 'Login', new_user_session_path%></li>
</ul>
</section>
</nav>
that i render in the application layout of the site (application.html.erb).
In some page the logouts links doesn't works and they generate a Hashtag on the url of the views (for example if i'm on the articles_path localhost:3000/articles the link add # near the /articles -> /articles#)
in the config/initializer of devise this string is uncommented:
# The default HTTP method used to sign out a resource. Default is :delete.
config.sign_out_via = :delete
and in the application.js i've got all the jquery links working fine:
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require foundation
//= require turbolinks
//= require_tree .
$(function(){
$(document).foundation();
});
and for final these are my routes:
Rails.application.routes.draw do
get 'show/index'
root to: "show#index"
devise_for :users
resources :categories
resources :articles
end

I think your issue may be related to turbolinks. Try disabling turbolinks for this page to validate whether this is the case. To your body tag add:
<body data-no-turbolink="true">
I believe that turbolinks is treating your logout link like a standard page link, preventing the actual functionality firing
EDIT
If you prove this is the case, focus disabling turbolinks to just the specific link that causes problems and remove the attribute from the body.
<%= link_to "Logout", destroy_user_session_path, :method => :delete, :data => { :no_turbolink => true } %>

#Phil's answer is correct. Rails 6.0.2.2 didn't require me to disable turbolink:
<%= link_to "Logout", destroy_user_session_path, :method => :delete %>

Related

How to set active_link_to on child elements to set active only?

I'm new to rails and I want to set active_link_to on child elements only. I'm using this gem https://github.com/comfy/active_link_to
Situation:
parent element path:
localhost:3000/columns // This one is set to active when going to that specific page
child element path:
localhost:3000/columns/post // This one will also be active also but the parent element is also active
I have this navbar:
<ul class="nav-bar">
<li class="nav-item">
<%= active_link_to columns_root_path, :class => 'nav-link' do %>
Columns
<% end %>
</li>
<li class="nav-item">
<%= active_link_to columns_post_path, :class => 'nav-link' do %>
Post
<% end %>
</li>
</ul>
How do I remove the active_link_to in the parent element If I only go to the child element. Because in my situation when I go to this path: localhost:3000/columns/post the columns and post path will be both set to active.
I have here in my routes file.
routes.rb
namespace :columns do
root 'columns#index', as: "root"
get 'post' => 'post#index'
end
Usually I set the folders into this one:
app/views/columns/columns/index.html.erb //for the columns index
app/views/columns/post/index.html.erb //for the post index
I am not familiar with the active_link_to gem. But readign at the documentation I would guess that the active: :exact option is what you are looking for.
<ul class="nav-bar">
<li class="nav-item">
<%= active_link_to columns_root_path, active: :exact, :class => 'nav-link' do %>
Columns
<% end %>
</li>
<li class="nav-item">
<%= active_link_to columns_post_path, active: :exact, :class => 'nav-link' do %>
Post
<% end %>
</li>
</ul>

Strange error blocks users from editing devise profile

I have an application under development in Rails 3.2.13 with devise, omniauth and cancan. It all worked perfectly until I started to implement authorisation with cancan. It is even more interesting that cancan itself works like charm but generates an error in editing the user profile provided by devise. If cancan does that at all, I'm really not sure.
The error message is:
No route matches {:controller=>"devise/posts"}
I have a posts controller, but that's not linked to devise by any means. This is the strangest part in the story.
I successfully localised the spot that generates it but I can't figure out what the cause of the problem is and how to fix it. So I have a menu shown only to admins in my application.html.erb , this is the source:
<% if (user_signed_in? && (current_user.role?("sysadmin") || current_user.role?("postadmin") || current_user.role?("testadmin"))) %>
<ul class="nav navbar-nav nav-pills">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" style="color: crimson;">
<span class="glyphicon glyphicon-cog"></span> Administration <b class="caret"></b></a>
<ul class="dropdown-menu">
<% if (current_user.role?("sysadmin") || current_user.role?("postadmin")) then %>
<li><%= link_to 'Posts', :controller => :posts, :action => :index %></li>
<% end %>
<% if (current_user.role?("sysadmin") || current_user.role?("testadmin")) then %>
<li><%= link_to 'Itests', :controller => :itests, :action => :index %></li>
<% end %>
</ul>
</li>
</ul>
<% end %>
What's really interesting is that if I delete the <ul>...</ul> block so to leave nothing but a naked if ... end block, it works. Also, it works for users not having any of the three admin roles.
But in the <ul>...</ul> block there's nothing else but HTML, Bootstrap styling and some inline ruby links to some other controllers.
How does this breaks the "edit profile" feature of devise?
Check out this question: Rails No route matches {:controller=>"devise/products"}
Basically you're in device namespace and you have to use path helpers:
<%= link_to 'Posts', posts_path %>
or:
<%= link_to 'Posts', :controller => '/posts', :action => :index %>

No route matches [GET] "/signout"

I saw a few postings related to this topic, but the given solutions did not really clarify things for me ...
So, I am working on a rails (version 3.2.2) application that followed the setup from Michael Hartl's Ruby on Rails tutorial. The application has a signout link, which worked well until recently, when it started giving me the error 'No route matches [GET] "/signout"'.
These are the relevant pieces:
routes.rb
match '/signout' => 'sessions#destroy', :via => :delete
sessions_controller.rb
def destroy
sign_out
redirect_to root_path
end
sessions_helper.rb
def sign_out
current_user = nil
cookies.delete(:remember_token)
end
_header.html.erb
<li>
<%= link_to "Sign out", signout_path, :method => :delete %>
</li>
All it takes for the signout to start working again is the removal of ":via => :delete" from the routes file. Is this the right approach or is there a better one? Also, why did the link stop working without any rails update?
Thank you,
Alexandra
On request, I added the full code for the _header.html.erb:
full _header.html.erb
<!-- ***** Initialized: Listing 5.24 ***** -->
<!-- ***** Updated: Listing 8.24 ***** -->
<!-- ***** Updated: Listing 9.7 ***** -->
<!-- ***** Begin: Listing 9.28 ***** -->
<header>
<header class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<% if signed_in? %>
<%= link_to "project manager", about_path, id: "logo" %>
<% else %>
<%= link_to "project manager", root_path, id: "logo" %>
<% end %>
<nav>
<ul class="nav pull-right">
<!--li><%= link_to "Home", root_path %></li-->
<% if signed_in? %>
<% if Rails.env.development? %>
<li><%= link_to "Overview", overview_path %></li>
<% end %>
<% if Rails.env.development? %>
<li id="fat-menu" class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"> Projects <b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><%= link_to "Status", projects_path %></li>
<li><%= link_to "Dev View", dev_projects_path %></li>
</ul>
</li>
<% else %>
<li><%= link_to "Projects", projects_path %></li>
<% end %>
<% if Rails.env.development? %>
<li><%= link_to "Teams", teams_path %></li>
<% end %>
<% if Rails.env.development? %>
<li id="fat-menu" class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"> Tasks <b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><%= link_to "Status", tasks_status_path %></li>
<li><%= link_to "Tree", tasks_tree_path %></li>
<li><%= link_to "Dev View", dev_tasks_path %></li>
</ul>
</li>
<% else %>
<li id="fat-menu" class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"> Tasks <b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><%= link_to "Status View", tasks_status_path %></li>
<li><%= link_to "Tree View", tasks_tree_path %></li>
</ul>
</li>
<% end %>
<% if Rails.env.development? %>
<li id="fat-menu" class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"> Reports <b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><%= link_to "Project Progress", analysis_path %></li>
<li><%= link_to "Revision History", history_path %></li>
</ul>
</li>
<% else %>
<li id="fat-menu" class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"> Reports <b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><%= link_to "Revision History", history_path %></li>
</ul>
</li>
<% end %>
<% if Rails.env.development? %>
<li><%= link_to "Help", help_path %></li>
<% end %>
<li id="fat-menu" class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"> Account <b class="caret"></b>
</a>
<ul class="dropdown-menu">
<% if current_user.admin? %>
<li><%= link_to "Admin", users_path %></li>
<% end %>
<% if Rails.env.development? %>
<li><%= link_to "Profile", current_user %></li>
<% end %>
<li><%= link_to "Settings", edit_user_path(current_user) %></li>
<li class="divider"></li>
<li>
<%= link_to "Sign out", signout_path, :method => :delete %>
</li>
</ul>
</li>
<% else %>
<li><%= link_to "Sign in", signin_path %></li>
<% end %>
</ul>
</nav>
</div>
</div>
</header>
<!-- ***** End: Listing 9.28 ***** -->
This thread is a bit old, but I thought I'd share a solution anyway as more people might be having the same problem.
Here is some background information on how this works before we get into the actual troubleshooting:
Notice that the Sign Out link looks as follows:
<%= link_to "Sign out", signout_path, :method "delete" %>
If you look at the source code generated by this tag, you will see this:
Sign out
Notice the part that says data-method="delete". With straight HTML, this won't work. If you click the link, your browser will simply ignore the DELETE instruction and instead submit a GET request to your server (this is what you are currently seeing in your log). To get your browser to submit a DELETE request, you will need to use some JavaScript magic. This is where the jquery_ujs.js file comes in (you will most likely be able to see a link to this file by Viewing Source in your browser; it should be in the header, close to, or included within the application.js file). If you look inside the jquery_ujs.js file, towards the middle of the file, you will see the following code:
// Handles "data-method" on links such as:
// Delete
In other words, the code above makes sure that your browser actually does submit a DELETE request (we don't have to get into the details of the actual code here).
Given this background information, there are two possible reasons why you are getting your error.
You are simply missing the jquery_ujs.js file
Other JavaScript code you have written or included is interfering with the desired
behavior of the jquery_ujs.js file
To troubleshoot, do as follows:
For 1) Load the page that contains your Sign Out link and select View Source from your browser. Make sure that the file jquery_ujs.js is in the header (or concatenated with the rest of your JS files into the application.js file, depending on your application settings)
For 2) In application.js, remove the //=require_tree . directive. Reload your page, and click the Sign Out link. If the Sign Out link is hidden under a menu that only works with your JavaScript installed, then just put a duplicate of the Sign Out link somewhere else on your page where it is accessible without JavaScript. Now try clicking on the link - it should hopefully work. If you are no longer getting the routing error, you know that this was the cause for your problem. The easiest way to troubleshoot this is to add back the //=require_tree . directive, but then to remove all your JavaScript files except the application.js file from the folder where they reside, and then to add back each file one by one, while you try the Sign Out link, until it no longer works. This will allow you to identify the troublemaker JavaScript file. Once you have identified this file, try removing all code (upon which the link should work again) and then adding back pieces of the code until it no longer works - voila, you have now identified the root of the problem! Please feel free to report back what it was. My guess is that it could be either a straight up error, a return false; statement, or a stopPropagation(); statement.
Hopefully this will work! Good luck.
Since the answers that I received in September 2012 did not solve my problem, I just ended up removing ":via => :delete" from the routes file, which made the signout link work again.
After reading eriklinde's answer, I went back to my code to see if his answer would help. The jquery_ujs.js file was not missing. So, I started looking into the second possible reason that was suggested. Nevertheless, when I went to the routes.rb file and added "via: :delete" to have a line reading "match '/signout', :to => 'sessions#destroy', via: :delete", the signout functionality continued working without a problem. Since "via: :delete" is different than ":via => :delete", which I previously removed, maybe this was causing the problem?
I think the solution is here:
Rails 3 link_to (:method => :delete) not working
Are you missing <%= javascript_include_tag :all %> in your page? It should go in your layout file.
I had this same problem and fixed it by rearranging the order of the requirements in the application.js file. Mine were ordered as such:
//= require jquery_ujs
//= require jquery
//= require bootstrap
//= require_tree .
and are now ordered like this
//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require_tree .
I literally did nothing else.
try changing the _header.html.erb partial to
<li>
<%= link_to "Sign out", signout_path, :method "delete" %>
</li>
Actually you are probably missing the cross site forgery protection tags. Which would explain the inability to delete via the delete method. Not sure why it was working before.
Add this to your layout file in the head section
for haml
= csrf_meta_tags
for erb
<%= csrf_meta_tags %>
My guess would be that somehow you don't have jQuery UJS installed / active.
One of the key features listed here is "make non-GET requests from hyperlinks." Try adding gem 'jquery-rails' to your gemfile, run bundle install from the command line, restart your server, and see if it works!
This should be in your application.js file (with no lines above it that don't start with //!)
//= require jquery
//= require jquery_ujs
try this :
just add into you application.js
//= require jquery_ujs

How do I link the same page in another language with the i18n gem for Refinery CMS?

I'm converting a site into the Rails based Refinery CMS, I've setup the i18n refinery cms gem and I've created multi-lingual versions of my pages. I'd like to create a locale switcher on the page, so that a user can click on a flag and switch between the various languages for the particular page that they are on.
How can I get the available languages for a page, and their respective links?
# In a controller
::I18n.locale = params[:locale]
<!-- In a view with a dropdown -->
<ul id="menu1" class="dropdown-menu" role="menu" aria-labelledby="drop4">
<% Refinery::I18n.frontend_locales.each do |frontend_locale| %>
<li>
<%= link_to Refinery::I18n.locales[frontend_locale], refinery.url_for(:locale => frontend_locale) %>
</li>
<% end %>
</ul>
<ul id="laguages">
<%
#page.translations.each do |t|
%>
<li>
<%= link_to "#{#page.translations.find_by_locale(t.locale).title} (#{Refinery::I18n.locales[t.locale]} #{image_tag("/assets/refinery/icons/flags/#{t.locale}.png")})".html_safe, refinery.url_for(:locale => t.locale) %>
</li>
<%
end
%>
</ul>

Twitter Bootstrap Pills with Rails 3.2.2

I followed the basic railscast for using Twitter Bootstrap in Rails application. Everything was great, until I had to push to heroku, then I had some problems with pg gem, and I had to rake assets:precompile to push it ok. Finally I solved.
Now, I'm trying to use pills in my application, I have copy/paste from documentation and changed the url in href :)
<div class="container">
<div class="row">
<div class="span3">
<p> Lorem Ipsum</p>
</div>
<div class="span9">
<ul class="nav nav-pills">
<li class="active">Home</li>
<li>Products</li>
<li>Categories</li>
</ul>
</div>
</div>
</div>
When I push one of the links, I'm redirected to the right url but the selected option doesn't change to class="active". I don't know why... I thought it was the javascript but hover property works ok... I mean, when the mouse is over an option (diferent from active) its style changes ok.
I tried rake assets:clean, but no change is made
Thanks
You actually have to handle this by yourself!
Your list should look something like
<li class="<%= 'active' if params[:controller] == 'yourdefaultcontroller' %>">Home</li>
<li class="<%= 'active' if params[:controller] == 'products' %>">Products</li>
<li class="<%= 'active' if params[:controller] == 'categories' %>">Categories</li>
You need to specify in each request which tab is the active one. You can do this by relying on the name of the controller (and action if need be) that is passed in the params hash.
You can use something like this:
<li class="<%= 'active' if current_page?(root_path) %>"><%= link_to "Home", root_path %></li>
<li class="<%= 'active' if current_page?(about_path) %>"><%= link_to "About", about_path %></li>
<li class="<%= 'active' if current_page?(contact_path) %>"><%= link_to "Contact", contact_path %></li>
I used a helper to implement this in the style of Rails' form helpers.
In a helper (e.g. app/helpers/ApplicationHelper.rb):
def nav_bar
content_tag(:ul, class: "nav navbar-nav") do
yield
end
end
def nav_link(text, path)
options = current_page?(path) ? { class: "active" } : {}
content_tag(:li, options) do
link_to text, path
end
end
Then, in a view (e.g. app/views/layouts/application.html.erb):
<%= nav_bar do %>
<%= nav_link 'Home', root_path %>
<%= nav_link 'Posts', posts_path %>
<%= nav_link 'Users', users_path %>
<% end %>
This example produces (when on the 'users' page):
<ul class="nav navbar-nav">
<li>Home</li>
<li>Posts</li>
<li class="active">Users</li>
</ul>

Resources