No route matches - after login attempt - even though the route exists? - ruby-on-rails

I am working on a rails application and added a simple login system according to a book.
I created the controller admin:
rails generate controller admin login logout index
It added the following routes to routes.db
get "admin/login"
get "admin/logout"
get "admin/index"
I can got to http://localhost:3000/admin/login there is no problem at all.
But when I try to login I get: No route matches "/admin/login"!
Now, the first confusing part is that the "login" method of my AdminController is not executed at all.
The second confusing part is that this code works like a charm - redirects everything to /admin/login:
def authorize
unless User.find_by_id(session[:user_id])
flash[:notice] = "you need to login"
redirect_to :controller => 'admin', :action => 'login'
end
end
Sidenotes:
I restarted the server several times.
I tried a different browser - to be sure there is no caching problem.

Try
match "/admin/login" => "admin#login"
match "/admin/logout" => "admin#logout"
match "/admin/index" => "admin#index"
(notice the leading /)
As an aside, unless you're creating a login system to learn about Rails and/or authentication, you're probably better off using something like Devise.

Following on from David Sulc's answer:
You're defining the routes as get requests, meaning to go to them you must perform a GET /admin/login request which is basically what happens when you type the URL into your address bar or follow a link that uses it.
However when you try to use these URLs in a form, the form does a POST request and because you've defined all of these as get-only requests, Rails will not be able to find a compatible route.
I definitely agree with David that you should look at an alternative system such as Devise.

Related

Rails Routes - link_to singular resource with params

so this is stumping me im not the best when it comes to routes at all, but what i am trying to achieve seems simple. what i have is a feature that is currently only accessible by a superuser and now i would like to extend that functionality to a portal_administrator. now to access the page you need a link_to that looks like this
= link_to('Data', portal_datum_path(current_portal.id), :id => :super_user_data_link)
which is routed with a match
match '/portal_data/:id', :controller => 'portal_data', :action => 'show', :as => 'portal_datum'
now this works just fine you end up with a url that has a id params. which is used in the page that it routes to. in fact there is a before filter that makes sure there is a id.
def load_portal
#portal = Portal.find(params[:id])
end
this would enable the susperuser to see what portal he was in just by looking at the url. now that i am extending this to the users i dont want them to see what portal id they are in, so i thought i would use a singular resource something along the following.
= link_to('Data', portal_data_path, :id => :super_user_data_link)
with a
match '/portal_data' => "portal_data#show"
so it routes to the same place but keeps the url clean. but obviously this dosent work. even if i hard code the before filer to accept the first portal it jsut throws a error
No route matches {:controller=>"portal_data", :action=>"show"}
but if i rake my routes its there?
i am sure what i am doing wrong is obvious any ideas?
All i had to do was make the :id an optional parameter like so...
match '/portal_data(/:id)'
And it works :) then in the controller look for...
def load_portal
#portal = Portal.find(params[:id] || current_portal.id)
end
...an portal id on the account if there wasn't one in the params.

How do I make it so that my application homepage defaults to user sign up, instead of sign in using devise?

I am using Rails 3 and devise and am trying to make it so that when a person comes to my web app, they are taken directly to the user registration sign_up link instead of the sign in link.
I'm pretty sure that I'm having this problem because my routes are configured like:
root :to => "babies#new"
Accessing the baby model requires a user to be logged in. To get around this I've tried changing this to:
root :to => "users#sign_up"
It doesn't seem to work? I get an error saying that I have an:
uninitialized constant UsersController
Can anyone suggest what I'm doing wrong?
Thanks in advance!
One of the solutions is to create separate controller say main and an action in it sign_up_redirect. Then configure your routes file like this:
root :to => "main#sign_up_redirect"
and write in that action next:
redirect_to new_user_registration_path
* path to registration can be different to you
The following error happens when the corresponding controller is not found. You should check whether you are having UsersController or UserController
uninitialized constant UsersController
Unless you are scoping the Devise routes, root :to => 'users#sign_up' doesn't exist. I would also highly recommend against setting any Devise route as your root as all of the Devise hooks redirect to root ie. after_sign_up, after_sign_in, after_update. I think that for the desired outcome you have two options.
First would be to simply put a sign up form on the page at your root url. You can follow the logic in this tutorial to accomplish this, obviously changing from sign in to sign up.
The second option that comes readily to mind is to create a passthrough controller that simply has an index action that redirects to the sign up page. Something like that could look like this.
class PassthroughController < ApplicationController
def index
redirect_to 'devise/registrations#new'
end
end
Either option is simple enough to implement.

Set Up Route for Accessing Private S3 Content

I've been following
https://github.com/thoughtbot/paperclip/wiki/Restricting-Access-to-Objects-Stored-on-Amazon-S3
and
Rails 3, paperclip + S3 - Howto Store for an Instance and Protect Access to try and get Paperclip's expiring links to work. I believe most of what I'm running into is one of the routing variety.
In my pieces_controller I put a method in like this
def download
redirect_to #asset.asset.expiring_url(1000)
end
And then in my routes, I put this:
match "pieces/download"
Then in my view I have:
<%= link_to download_asset_path(piece)%>
It would seem to be far from working, and I'm not sure what is messed up. I know I'm getting routing errors for one, but it's also telling me that my download_asset_path is undefined, which is likely also routing related... I feel like I'm doing everything all wrong.
Tearing my hair out. Thanks!
Try modifying your routes file to:
match 'pieces/download' => 'pieces#download', :as => 'download_asset'
Your match needs to tell which controller#action to go to, and the as option will allow you to name the route download_asset_path.
If your pieces controller is for a Piece resource it could be cleaner like:
resources :pieces do
member do
get :download
end
end
But then you would want to change the link to:
link_to 'Link text', download_piece_path(piece)
For further reading: http://guides.rubyonrails.org/routing.html

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.

New Action Not Working

I have a standard User controller with the normal set of actions (index, show, new, edit, etc) and I'm trying to add a new action named 'profile'. I added the following code:
def profile
#user = User.find(session[:user_id])
end
I also created a new view for the action (app/views/users/profile.html.erb), but whenever I try to view that page I get an error:
ActiveRecord::RecordNotFound in UsersController#show
Couldn't find User with ID=profile
...
Apparently it's hitting the show action. I'm guessing that means I need to add something to my routes to make this work, but I don't know what. So far I just have the two default routes and the map.root line which I uncommented:
map.root :controller => "home"
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
So really I have two questions:
What do I have to do in order to enable my new action?
Why don't the existing routes cover this situation? Other urls consisting of just the controller and action work just fine (e.g. http://localhost:3000/users/new). Why not this one? Shouldn't it just evaluate to :controller = users, :action = profile, :id = nil?
Try putting something like this in your routes.rb file:
map.user_profile '/users/:id/profile', :controller => "users", :action => 'profile', :conditions => {:method => :get}
I think possibly the reason it's doing this is because you are not matching either of the defaults, because you are not setting :id (even though it is detecting your action as the id). I don't know what your URL looks like, but I have a feeling that if you tried http://localhost:3000/users/123124124/profile, it MIGHT work, even without the new line in routes.
Are you intentionally trying to get the id from session[:user_id] instead of params[:id]? Is this supposed to be displaying a public profile?
Are you sure, that the session contains the user_id the first time you load the page?
Hard to say without seeing all the code, but my guess is there may be some strangeness because your model and controller have the same name. I'd try renaming the controller before changing anything else (remember to change the name of the views/users directory too).
See also this other stack overflow post: Rails cannot find model with same name as Ruby class
Long shot maybe.
Solution for your problem configure your routes.rb in such a way that id should be passed as the parameter .
configure in routes.rb as below
map.profile '/profile/:id',:controller=>'users',:action=>'profile'
when you want to access your profile page use it with the following URL
http://localhost:3000/profile
Make sure once you login , u handle the session and store the userid in the session variable .
Good luck !

Resources