Rake routes not showing the route, but it exists when hardcoded - ruby-on-rails

I'm using Devise and Omniauth for my login process. For some reason, I can access the route "users/auth/facebook" or "users/auth/twitter" just fine. But they don't show up when I do rake routes, so I have no idea what the helper method to get these paths is (e.g. something_something_path). Can someone help me out?
I can't show all of my routes, but I can say that the only route that matches "/users/auth/..." that's showing up is this one (from rake routes):
user_omniauth_callback /users/auth/:action/callback(.:format) {:action=>/(?!)/, :controller=>"users/omniauth_callbacks"}
BTW, when I say I "can access the route just fine", I mean this works (redirects me correctly to facebook or twitter):
<%= link_to "Connect", "users/auth/facebook" %>
Also, the routes should be the default Devise omniauth routes for the user model

With regard to why this doesn't show up in rake routes, first note how the task is implemented. It is part of railties, and it gets the routes to show as such:
Rails.application.routes.routes
So we can see that it is asking the Rails.application for its routes.
Next note that the Omniauth gem "is a flexible authentication system utilizing Rack middleware".
Because it uses Rack middleware it does not 'know' anything about the Rails.application used by rake routes, and so its routes don't appear in that task.
You can get a good introduction to Rack middleware in this Railcast.
Delving a little deeper we can see from rake middleware that OmniAuth::Builder appears before your rails app in the stack. So how does it handle the auth/twitter route?
It does so by checking for a request_path in its call, you can see the check here, and you can see how the request_path is built here (path_prefix is auth by default, and name in your case is twitter.
When using Omniauth with Devise, the path_prefix is set automatically, as noted here.

Why they dont show up on rake routes, I am not sure. But if you wanna know their alias you can find them in here: https://github.com/plataformatec/devise/wiki/OmniAuth%3A-Overview
From their docs:
Currently, Devise only allows you to make one model omniauthable.
After making a model named User omniauthable and if "devise_for
:users" was already added to your config/routes.rb, Devise will create
the following url methods:
user_omniauth_authorize_path(provider)
user_omniauth_callback_path(provider)
So if you have devise_for :model in your routes you should see that url method.
Example:
<%= link_to "Sign in with Facebook", user_omniauth_authorize_path(:facebook) %>
Also if you take a look at the implementation of devise, you can see that the URL helpers are there:
https://github.com/plataformatec/devise/blob/master/lib/devise/omniauth/url_helpers.rb

Related

Rails 5.1 mailer error - account activation parameter in templates

I'm following Mike Hartl's Rails tutorial & ran into an issue when creating email templates. (Please note the tutorial is based on Rails 5.0.1, while I'm plowing ahead with Rails 5.1.1.)
The tutorial uses :activation_token & :activation_digest attributes to handle the security risks of signup URLs, and a :create_activation_digest hook to set their values before creating the User model.
Here's the mailer view template:
<%= link_to "Activate", edit_account_activation_url(#user.activation_token, email: #user.email) %>
The issue appears to be telling Mailer to use the value of :activation_token in the :id field of the route. (A URL definition error)
Here's the route definition, from rails routes:
edit_account_activation GET /account_activations/:id/edit(.:format) account_activations#edit
The error feedback:
No route matches {:action=>"edit", :controller=>"account_activations", :email=>"test7#example.com", :format=>nil, :id=>nil}, possible unmatched constraints: [:id]
I've tried hard-coding id: #user.activation_token in the mailer template, to no avail.
This seems like a easy one, but I'm stumped and a little worried that I'm overlooking something hidden in the transition from Rails 5.0.x to 5.1.x. Any ideas?
You are getting this error because in your config/routes.rb file, you GET /account_activations/:id/edit. That makes it necessary to send an ID which you don't want/need to do. Now I know that Rails Tutorial uses :id for token. But you're not defining id: in your link. So either you need to change the route, or change the link.
<%= link_to "Activate", edit_account_activation_url(id: #user.activation_token, email: #user.email) %>
Notice I define id:. Normally outside this tutorial though, you should consider changing your route to GET /account_activations/edit/:token and then look up the user by token.
Thanks all,
But the error was related to how I defined the :activation_token hook in the User model. All tests now pass.

The method to redirect from one page to other on ruby on rails

In my code, I use something like:
<li><%= link_to "Find a meal", {:controller =>'microposts', :action => 'index'} %></li>
to redirect to another page.
When I studied the mailbox part, I mentioned the code is:
<li><%= link_to "Inbox", mailbox_inbox_path %></li>
And this kind of notations appear in other places of this tutorial as well. I thought mailbox_inbox_path is a variable already defined somewhere. But I can't find it.
This is the tutorial of inbox messaging.
mailbox_inbox_path is not a variable. It's a route helper method generated by Rails based on your routes definition in your routes.rb file. Do a:
bundle exec rake routes
Then, you will be able to see all the available routes for your Rails app and in the leftmost column, you will see the Rails generated helper methods. Just add a _path or _url to them and you can use them in your views rather than manually specifying controller and action to link_to.
In your particular example from the tutorial, you have the following in the routes.rb file:
get "mailbox/inbox" => "mailbox#inbox", as: :mailbox_inbox
Now, if you do a: bundle exec rake routes, you will see this:
Prefix Verb URI Pattern Controller#Action
mailbox_inbox GET /mailbox/inbox(.:format) mailbox#inbox
So, in the leftmost column you see mailbox_inbox which is generated by Rails and you can use this mailbox_inbox_path or mailbox_inbox_url in your views as they are available as view helper methods.
See this documentation and resources documentation for some more information on this.
try this command and you will find all such helper methods for mailbox controller
bundle exec rake routes | grep mailbox

Rails 4 + Devise + Routing Error

I'm attempting to install Devise on a rather simple event creating/displaying Rails 4 app. I have 2 static pages and the index page displaying without authentication, and all is well there. Anything else kicks you to the "sign up" page. From there, when I attempt to create an account for myself (to simply see the other pages- simple vanilla devise installation attempt) I get a "No route matches [POST] "/registrations/user" error when clicking "submit" (f.submit)
I am using Rails 4, have the 3.0.3 version of Devise, bundled it, ran "rails generate devise:install" to install it, ran "rails generate devise user", ran db:migrate, raked the routes, and restarted the Rails server.
I even recreated the button action with the "correct" route and "get post" - no dice.
Anybody have any idea? I'm at a loss here.
Well it's always tricking debugging sever-side code without seeing it in action, but here's what should work.
yourappname/config/routes.rb :
devise_scope :user do
# matches the url '/register' to the registration controller's 'new' action and creates a :register symbol inorder to reference the link dynamically in the rest of the code
get 'register', to: 'devise/registrations#new', as: :register
end
(Assuming your register button is in your app's partial)
yourappname/app/views/layouts/application.html.erb:
<%= link_to "Register", register_path, class: "btn" %>
Now you could actually put that link_to anywhere, in any page, and it'll work. The reason for this is the 'register_path'.
When you create your route, the as: :register parameter creates a global variable that can be accessed throughout your app.
the register_path variable in your link_to method will always call the right action, even if you change your routes file.
It's just syntax. You could create any symbol you want. This would also work:
routes.rb:
# Inside get method, third parameter
as: :bowtiesarecool
someview.html.erb:
# Inside link_to method, second parameter
bowtiesarecool_path
Just match the variable name with the symbol name and a put a _path after it. The link_to method will handle everything else!

rails 3.1 devise confirmable

I have set up rails with devise however I can't get my authentication to work when I add the confirmable module to my application. I included the confirmable module in my User model and uncommented confirmable and the add_index confirmation token in my migration file. After rolling back the database and re-commenting these, the authentication works as specified.
I have also checked and I can't sign out of the application, even though I have provided the <%= link to "Sign Out", destroy_user_session_path %> My application gets a routing error, no route matches [GET] users/sign_out. When I run rake routes this route is available to me as
destroy_user_session DELETE /users/sign_out(.:format) {:action=>"destroy", :controller=>"devise/sessions"}
Not sure about the confirmable part, but I can tell you that the link you're using is calling a GET method. As you can see, to sign out you need a DELETE method in your link which will look like this:
<%= link_to "Sign out", destroy_user_session_path, :method => :delete %>
If you want to use GET for sign out specifically, check out the devise initializer file; somewhere at the bottom you'll see something about signing out and the default method being :delete. put this line there:
config.sign_out_via = :get
The work around that I applied is as follows: I had a conflict with the blueprint framework as it already provides an alert and notice class. If you look at devise's wiki it will have a subsection that deals with this issue. Then in order to confirm a new user, I went into the console, found the first user, and used the provided confirm! method that devise has in its documentation.

Devise messing with my routes

I recently turned to devise for my authentication routine. However, i'm still having some problems with it and mainly with routing. After a user logs in, i have the routes :
devise_for :users
namespace :user do
root :to => "town#index"
end
After i log in, i'm redirected to town controller. There i have this line :
<%= link_to raw("<p class='menu_head'>#{t('menu.inventory')}</p>"), :controller => "character" %>
This actually worked well with restful authentication, but for devise to work i have to specify the controller as "/character", else i get a :
No route matches {:controller=>"user/character"}
Though this route is incorrect. How can this be fixed ?
Moreover, i think this one is caused by devise once more. When a new user signs up, devise redirects them to town#index as it would happen if they have logged in. When this happens, for some reason current_user is not initialized. This only happens after sign up not when a user logs in. I'm pretty sure that i'm doing something wrong with devise.
You should be using the routing helpers rather than the options to get to this controller. Define a path helper in your routes file and use that instead. This way, you'll always be given the right URL.
At the moment, your application is sending you to users/town because that's what you're telling it to. The URL for sign in is /users/sign_in and by passing :controller you're saying "go to /users/town. If you were using named routes this would not occur.

Resources