Devise destroy_user_session_path on heroku - ruby-on-rails

I am trying to log out a user from a (test) site in production on heroku.
The problem is heroku transforms this <%= link_to 'Logout', destroy_user_session_path, method: :delete %> in a GET /users/sign_out
I've tried this <%= link_to 'Logout', destroy_user_session_path, method: :delete, :data => { :no_turbolink => true } %> as suggested here Devise destroy_user_session_path does'nt work
I've found some solutions in reply to destroy_user_session_path is triggering GET instead of DELETE in Rails but I don't feel comfortable with the answers as I'd like to avoid a GET.
Logout was ok in development, so I checked on https://devcenter.heroku.com/ and made some modifications, but I am still stuck.
I worked on the asset pipeline and added these gems:
gem 'rails_serve_static_assets'
gem 'rails_stdout_logging'
These gems are probably useful in other cases, but not mine (I also have a problem with links to images that don't persist).
EDIT
Here is my full template
<div class="" style="background-color: #1a252f;">
<ul class="nav justify-content-center">
<% if user_signed_in? %>
<li class="nav-item">
<%= link_to 'Edit account|', edit_user_registration_path %></li>
<li class="nav-item">
<%= link_to 'Logout', destroy_user_session_path, method: :delete, :data => { :no_turbolink => true } %></li>
<% else %>
<li class="nav-item">
<%= link_to 'Login', new_user_session_path %></li>
<% end %>
</ul>
</div>
EDIT 2
I've also tried this in routes.rb:
devise_for :users do
get "/users/sign_out" => "devise/sessions#destroy", :as => :destroy_user_session
end
and I still get a status 404 in the heroku logs.

The solution provided here: destroy_user_session_path is triggering GET instead of DELETE in Rails was the one for me,
i.e. with config.sign_out_via = :get in devise.rb

Related

No route matches [GET] "/users/sign_out" **Rails 5/Bootstrap 4**

I am running Rails 5 and updated Bootstrap to version 4 in an existing app which uses Devise.
Before updating Bootstrap, the routes were working fine. Now, when the user selects sign-out, they receive the following message:
No route matches [GET] "/users/sign_out"
Here is part of the header code:
<% if current_user %>
<a class=<%= link_to 'Classes', tracks_path %></a>
<a class=<%= link_to 'Edit profile', edit_user_registration_path %></a>
<a class=<%= link_to 'Sign out', destroy_user_session_path, method: :delete %></a>
And Rake Routes shows:
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
Is there a reason that the change to Bootstrap 4 would trigger this error? I have followed all of the instructions on the Bootstrap repo for installation.
The problem is you're rendering your link tags inside the class attribute:
<a class=<%= link_to 'Sign out', destroy_user_session_path, method: :delete %></a>
So that results in malformed output which ignores that you specify method: :delete. This is what you're looking for:
<%= link_to "Sign out", destroy_user_session_path,
method: :delete, class: 'nav-link' %>

link_to doesn't work, controller appears as a html attribute

I have been googling last 2 hours and unfortunately I cannot fix this, though I thought it must be easy.
<%= link_to 'Log Out', {:controller => 'static_pages', :action => 'index'} do %>
<i class="glyphicon glyphicon-log-out link-icon"></i>
<% end %>
This the code I have. So, I need "Log Out" link to appear with log-out icon, which is from bootstrap. But HTML output of this code is this:
<a controller="static_pages" action="index" href="Log Out">
<i class="glyphicon glyphicon-log-out link-icon"></i>
</a>
I tried many ways to fix this, but I also tried removing "do" so, I can see if it causes the problem. This is the link after I removed "do":
<%= link_to 'Log Out', {:controller => 'static_pages', :action => 'index'} %>
HTML output of this is:
Log Out
It doesn't make sense. Because I have same link_to in my footer and it works. Footer:
<%= link_to 'Log In', {:controller => 'users', :action => 'login'} %>
Footer output:
Log In
So, why this isn't working in another page? Thank you.
When you pass a block to the link_to helper this will be a body for it.
<%= link_to :controller => 'static_pages', :action => 'index' do %>
<i class="glyphicon glyphicon-log-out link-icon"></i>
Log Out
<% end %>

Link not working in RoR

I have this link
<li><a href="<%= destroy_user_session_path(:method => :delete) %>"><button
class="button icon-left ion-ios7-compose">Log out</button></a></li>
But it is not working. How do I fix the :method => :delete so that it works in the link?
I am getting this error:
No route matches [GET] "/users/sign_out"
Also, I am using devise for users.
use the link_to helper (also check out your html, a button isn't usually found inside a link).
<li><%= link_to 'Log out', destroy_user_session_path, method: :delete %></li>
You have to write it like this
<li><%= link_to "Log Out", destroy_user_session_path, :class => "button icon-left ion-ios7-compose", :method => :delete %></li>

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 %>

How do I apply an 'active' class to my navigation based on the current_page in a DRY way? - Rails 3

So in my application.html.erb I have my navigational structure that looks something like this:
<div id="navigation">
<ul class="pills">
<% if current_page?(:controller => 'welcome', :action => 'index') %>
<li><%= link_to "Profile", vanity_path(:vname => current_user.username) %></li>
<li><%= link_to "Settings", settings_path %></li>
<li><%= link_to "Sign Out", signout_path %></li>
<% elsif !current_page?(:controller => 'welcome', :action => 'index') %>
<li><%= link_to "Home", root_path %></li>
<li><%= link_to "Profile", vanity_path(:vname => current_user.username) %></li>
<li><%= link_to "Settings", settings_path %></li>
<li><%= link_to "Sign Out", signout_path %></li>
<% end %>
</ul>
</div>
However, what I would like to do, is once they are on any of the pages in the navigation, it applies a class active to the respective link.
So for instance, if the user is on mydomain.com/johnbrown which is the Profile link, the rails helper would look something like this:
link_to "Profile", vanity_path(:vname => current_user.username), :class => "active".
But how do I do that in a programmatic way, so I am not duplicating content? i.e. how do I get that functionality for all the pages in my navigation and write it as DRY as possible?
Thanks.
This is a really great question. I've never really been happy with the solutions I've seen or come up with. Maybe we can get one together here.
Here is what I've tried in the past
I've made a helper that returns a hash with :class defined since I use HAML
def active_tab(path)
request.path.match(/^#{path}/) ? { :class => 'active' } : {}
end
ex usage:
= link_to "Dashboard", dashboard_path, active_tab("#{dashboard_path}$")
Or an alternative along the same lines
def active_class(path)
request.path =~ /#{path}/ ? 'active' : nil
end
ex usage:
= link_to 'Presentations', admin_presentations_path, :class => "#{active_class('presentations')}"
I would love to see some other suggestions on this.
I found this answer for a bootstrap related navbar but you could easily use it with your nav.
Answer taken from here
You can use helper for handle "current_page?", example a method :
module ApplicationHelper
def is_active?(link_path)
if current_page?(link_path)
"active"
else
""
end
end
end
example bootstrap navbar
<div class="navbar">
<div class="navbar-inner">
<a class="brand" href="#">Title</a>
<ul class="nav">
<li class="active">Home</li>
<li>Link</li>
<li>Link</li>
</ul>
</div>
</div>
So, on view looks like
<li class="<%= is_active?(some_path) %>">
<%= link_to "name path", some_path %>
</li>
For Haml
Just simple looks like :
%ul.nav
%li{class: current_page?(some_path) && 'active'}
= link_to "About Us", some_path
You may define a helper method in application_helper.rb
def create_link(text, path)
class_name = current_page?(path) ? 'my_class' : ''
content_tag(:li, class: class_name) do
link_to text, path
end
end
Now you can use like:
create_link 'xyz', any_path which would render as
<li class="my_class">
xyz
</li>
Hope it helps!
Why don't you just take the redundant parts out of the if else block? Also take a look at 'link_to_unless'
<div id="navigation">
<ul class="pills">
<li><%= link_to_unless(current_page?(:controller => 'welcome', :action => 'index'), "Home", root_path %></li>
<li><%= link_to "Profile", vanity_path(:vname => current_user.username) %></li>
<li><%= link_to "Settings", settings_path %></li>
<li><%= link_to "Sign Out", signout_path %></li>
</ul>
</div>
then I would add some jQuery to inject active class into the link that matches the window.location pattern.

Resources