Haven't been able to find anything specific to this issue (other searches deal with forms and such). It's probably a simple oversight on my part. But what on earth am I missing?
GOAL: I'm simply trying to redirect from the /login page URL to the /dashboard URL if a session exists.
EXPECTED OUTCOME: Calling redirect_to dashboard_index_url or redirect_to '/dashboard' should go to https://mydomain/dashboard
CURRENT OUTCOME: if I go to https://mydomain after creating a session it redirects me to https://mydomaindashboard, note the missing slash
ATTEMPTED SOLUTIONS:
Manually type the URL https://mydomain/dashboard after creating a session, RESULT: works, so the proper route seems to exist
Make manual route in routes.rb, RESULT: behavior is exactly the same as resource routing with the missing slash
Clear browser cache, use different browswers RESULT: all exhibit same behavior
Here's what I have (abbreviated to relevant parts):
class LoginController < ApplicationController
def index
redirect_to dashboard_index_url if session[:user_id]
end
#...
end
class DashboardController < ApplicationController
before_action :require_login # calls redirect_to root_url unless session[:user_id]
def index
#...
end
end
# In routes.rb:
resources :login
resources :dashboard
# have also tried things like (removed the above line for these)
get 'dashboard' => "dashboard#index"
#Ryan Here is the current output for the routes:
$ rake routes
Prefix Verb URI Pattern Controller#Action
login_index GET /login(.:format) login#index
POST /login(.:format) login#create
new_login GET /login/new(.:format) login#new
edit_login GET /login/:id/edit(.:format) login#edit
login GET /login/:id(.:format) login#show
PATCH /login/:id(.:format) login#update
PUT /login/:id(.:format) login#update
DELETE /login/:id(.:format) login#destroy
dashboard GET /dashboard(.:format) dashboard#index
dashboard_index GET /dashboard(.:format) dashboard#index
POST /dashboard(.:format) dashboard#create
new_dashboard GET /dashboard/new(.:format) dashboard#new
edit_dashboard GET /dashboard/:id/edit(.:format) dashboard#edit
GET /dashboard/:id(.:format) dashboard#show
PATCH /dashboard/:id(.:format) dashboard#update
PUT /dashboard/:id(.:format) dashboard#update
DELETE /dashboard/:id(.:format) dashboard#destroy
root GET / login#index
SOLVED:
Well, I found the problem and it was not actually Rails, it was Apache-Passenger. There was a config with a redirect (so that all HTTP get redirected to HTTPS) at the apache level that didn't have the trailing slash floating around and causing trouble. (smacks forehead)
Gotta love those red herrings. Thanks so much guys for the quick help!
for use dashboard_index_url, you have to write it in your routes file. However as you've created in routes.rb a dashboard resource, a dashboards_url is available to you and it leads to /dashboards/index
Other way to nail this task is create a mapping
get 'dashboard' => "dashboard#index" as: :dashboard_index
and dashboard_index_url and dashboard_index_path will be available for you
Update 1
Please, look on this SO question
the problem is that path give you relative route and url - absolute. that's why you don't have additional slash in your path. Try path instead of url and it should work.
Update 2
try dashboard_index_path
How about changing your routes to
get '/login', to: redirect('/dashboard')
You can even tailor the resulting link to something more specific to your user by
get '/login', to: redirect('/dashboard'), as: '/dashboard/user[:username]' if you need to.
On a side-note, you should try cleaning up your routes as you go. There are a lot there that you are not using. Change it to
resources :dashboard, only: [:index] and add to it as you need. E.g only: [:index, :show] etc. If another developer was needed to modify your app one day we'd look at your routes and perhaps make incorrect assumptions about what we can do.
Justin
Related
I'm currently adding proper routes into a legacy rails application, I can't seem to use PATCH, PUT and DELETE routes as the way the app works currently it only goes based on GET and POST routes.
So I've implemented REST routes but for the time being, I need to redirect PATCH, PUT and DELETE until such time we can change it to use proper routing.
Here's what I get while updating:
These are the routes for custom fields# custom_fields
resources :custom_fields, except: %i[show destroy] do
get :disable, on: :member
collection do
get :list
get :edit
get :disable
get :enable
get :order_fields
post :process_order_fields
end
end
# remap wrong implmentation of paths
get '/custom_fields/edit/:id', to: redirect('/custom_fields/%{id}/edit')
I've tried the following
post '/custom_fields/:id', to: redirect(custom_field_path(id: %{id}))
but no dice.
I don't understand your question. Why do you "need" to add these redirects?
If you wish to define a legacy POST route like post '/custom_fields/:id', but internally have it perform the same action as the non-legacy PUT/PATCH request, then just define it as such:
resources :custom_fields, except: %i[show destroy] do
post :update, on: :member
# ...
end
Moreover, it is invalid to define this as a redirect as you attempted, according to the HTTP specification:
If the 302 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.
So this is the path for all my users:
http://localhost:3000/users
I would like to change /users to /members , so I did this:
get '/members' => 'users#index', as: "members"
This way, people can visit http://localhost:3000/members and get all the same content in /users .
But the problem is that http://localhost:3000/users is still accessible to people. How can I remove/hide/redirect /users, so that people will see /members when they try to use this old /users url: http://localhost:3000/users ?
Well, it depends on if you want to eliminate the path or simply override it
Since you mention that http://localhost:3000/users still maps somewhere, I'm going to assume that you have either the line get '/users' => 'users#index' or more likely something like resources :users. If you have the first line, simply delete it, if it's the second you can restrict the routes that you create with the :except option
resources :users, except: :index
For a redirect, the solution hamdi posted should work as well.
Check out rails routings page for more info: http://guides.rubyonrails.org/routing.html
Cheers
You can redirect like the below:
get '/users', to: redirect('/members')
Also you can find more info for redirection at the below link:
http://guides.rubyonrails.org/routing.html#redirection
I have defined three routes in routes.rb
Rails.application.routes.draw do
root to: 'pages#lottery'
get 'pages/about'
get 'pages/contact'
get 'pages/lottery'
end
And when I run "rake routes" in my command line, I get the following:
Prefix Verb URI Pattern Controller#Action
root GET / pages#lottery
pages_about GET /pages/about(.:format) pages#about
pages_contact GET /pages/contact(.:format) pages#contact
pages_lottery GET /pages/lottery(.:format) pages#lottery
But when I got to the localhost:3000/pages/contact I get the error:
"No route matches [GET] "/pages/contact.html.erb"
And also "You don't have any routes defined!"
Does anybody know the problem?
Ugh rookie mistake. I had two tabs open in my command line. My rails s pages was in a different directory. Thanks for the help everyone, I appreciate it.
You should not be going to the URL /pages/contact.html.erb, it should be just /pages/contact.html.
Rails provides nice helpers to make it easy to get the right path, for example, pages_contact_path (from your rake routes).
Your pages_controller.rb should consist of three methods based on your routes listed.
pages_controller.rb
class PagesController < ApplicationController
def lottery
end
def about
end
def contact
end
end
views/pages/contact.html.erb
<p>Hello World</p>
Start up your rails server - rails s and navigate to localhost:3000/pages/contact and you should see Hello World
I am trying to set up routes for the "Page" model nested within the "User" model. Only "Pages" needs to be resourcesful. (User has_many pages)
This is the original way I did it:
resources :users, path: '', only: [] do
resources :pages, path: ''
end
The above worked for me just fine. The routes I got were these:
user_pages GET /:user_id(.:format) pages#index
POST /:user_id(.:format) pages#create
new_user_pages GET /:user_id/new(.:format) pages#new
edit_user_pages GET /:user_id/:id/edit(.:format) pages#edit
user_pages GET /:user_id/:id(.:format) pages#show
PUT /:user_id/:id(.:format) pages#update
DELETE /:user_id/:id(.:format) pages#destroy
This made sense for me because /john-doe/page1 would be user_pages_path(#user, #user.pages.first).
However, new_user_pages didn't make sense because a user can only make a page for himself/herself. Therefore, each user should visit /new, not "/:user_id/new". Furthermore, what happens if the user visits another user's ":another_user_id/new" ? (it would make more sense to do new_pages_path and '/new' instead of new_user_pages_path and /:user_id/new).
Another way I tried to do the above routing:
I also realized the above can be accomplished in a shorter way due to the fact that ":users" does not need to be resourceful:
resources :pages, path => :user_id
However, this resulted in paths w/o "user" in them:
pages GET /:user_id(.:format) pages#index
POST /:user_id(.:format) pages#create
new_pages GET /:user_id/new(.:format) pages#new
edit_pages GET /:user_id/:id/edit(.:format) pages#edit
pages GET /:user_id/:id(.:format) pages#show
PUT /:user_id/:id(.:format) pages#update
DELETE /:user_id/:id(.:format) pages#destroy
What is the "rails" way of doing this? Also, should I remove "new" from the resource and define it separately?
Also, does it make sense to use scope or namespace instead?
Thanks,
Nick
Why don't you want your routes to follow the new_user_pages_path format? There might be reasons for doing it the way you want that I'm not aware of, but for me, it's a lot easier when all of my nested resource paths follow the same format.
To answer your question about preventing a user from visiting /:another_user_id/new, you can prevent this by adding a before_filter to make sure that the id getting passed to the new action matches the id of the user that is currently logged in.
This is what I'm using in the app I'm building currently:
things_controller.rb
class VendorsController < ApplicationController
#other filters
before_filter :correct_user
#controller methods
private
def correct_user
if params[:user_id]
#user = User.find(params[:user_id])
unless #user && current_user == #user
redirect_to(root_path)
end
else
redirect_to(root_path)
end
end
end
Of course, you'll need a current_user method for this to work (mine comes from devise).
Im trying to figure out how to get a dynamic link for example
/users/user1/show
/users/user1/edit
or
/profiles/1/
How would I create a route that I could insert in my views like a view_profile_path and that would include the id or username of a user?
in config/routes.rb you need to add 1 simple line:
resources :users
and get all this stuff
HTTP Verb Path action named helper
GET /users index users_path
GET /users/new new new_user_path
POST /users create users_path
GET /users/:id show user_path(:id)
GET /users/:id/edit edit edit_user_path(:id)
PUT /users/:id update user_path(:id)
DELETE /users/:id destroy user_path(:id)
You can read about rails routes in the guides
Actually, I think you need something like this in config/routes.rb
resources :users do
resources :profiles
end
You can later check your REST-ful resource routes by issuing the command:
rake routes
This way you have a more natural approach to your routes in which your users will be bound to one or more profiles, therefore you may use something like:
user_profile_path(#user)
to create an appropriate link to a user's profile.