11

After having watched Ryan's excellent Railcast Simple OmniAuth, I've managed to implement authentication in my app.

Everything is working fine, but in my view I have links that look like this:

<%= link_to 'Sign in with Twitter', '/signin/twitter' %>
<%= link_to 'Sign in with Facebook', '/signin/facebook' %>

I was wondering if there is an elegant way to create a named route to replace that with:

<%= link_to 'Sign in with Twitter', signin_twitter_path %>
<%= link_to 'Sign in with Facebook', signin_facebook_path %>

or:

<%= link_to 'Sign in with Twitter', signin_path(:twitter) %>
<%= link_to 'Sign in with Facebook', signin_path(:facebook) %>

OmniAuth already handles those routes... In my routes.rb file I only have stuff for callbacks and signing out:

match '/signin/:provider/callback' => 'sessions#create'
match '/signout' => 'sessions#destroy', :as => :signout

So I don't know where I could create those named routes.

Any help will be appreciated. Thanks.

BryanH
  • 5,826
  • 3
  • 34
  • 47
Daniel Perez Alvarez
  • 6,570
  • 5
  • 28
  • 27

3 Answers3

15

Notice that in link_to, you're just providing a string for the route argument. So you can just define a method in a helpers file.

# application_helper.rb
module ApplicationHelper
  def signin_path(provider)
    "/auth/#{provider.to_s}"
  end
end

# view file
<%= link_to 'Sign in with Twitter', signin_path(:twitter) %>

If you want to get all meta

# application_helper.rb
module ApplicationHelper
  def method_missing(name, *args, &block)
    if /^signin_with_(\S*)$/.match(name.to_s)
      "/auth/#{$1}"
    else
     super
    end
  end
end

#view file
<%= link_to 'Sign in with Twitter', signin_with_twitter %>
monocle
  • 5,866
  • 2
  • 26
  • 22
  • 5
    How does this work with an application deployed to a Sub-URI? – graywh Sep 23 '11 at 21:48
  • How would you handle additional parameters? (e.g. the 'origin'-parameter). Ideally signin_path would accept all parameters a regular *_path method would. – Marc Feb 26 '13 at 15:08
  • 2
    Also, how would you make this method available to controllers? – Marc Feb 26 '13 at 15:16
  • Although, it is an old answer and comments, but for the sake of completeness [this question](http://stackoverflow.com/q/13613223/673826) answers about controllers as well. – mlt Nov 07 '16 at 21:38
3

Add this to your routes.rb

get "/auth/:provider", to: lambda{ |env| [404, {}, ["Not Found"]] }, as: :oauth

Now you can use oauth_path url helper to generate urls.

Eg. oauth_path(:facebook) # => /auth/facebook

Agent47DarkSoul
  • 448
  • 5
  • 13
-6

With Rails 3 you can do :

# routes.rb
match '/signin/:provider/callback' => 'sessions#create', :as => :signing

#view.erb
<%= link_to 'twitter', signing_path(:provider => 'twitter') %>
<%= link_to 'facebook', signing_path(:provider => 'facebook') %>
gbelleguic
  • 13
  • 1
  • 12
    This will incorrectly create a link to the *callback* URL, instead of the OmniAuth redirect URL of '/auth/:provider'. – Dale Campbell May 05 '12 at 23:34