Rails Routes Question - ruby-on-rails

I have a really simple app I've built using RoR but I'm stuck modifying my routes.
It's basically a site which lists user information - I need to change the url from:
mydomain.com/users/user-1
to
mydomain.com/user-1
Update..
I've managed to route the above request using:
match "/:id", :controller=>"users", :action=>"show"
But what I really need to do is change the route for all requests to /users/# to /
Although my route is working, all my links to show a user still point to:
/users/user-#
--- Update ---
The routing for /user-id is now working perfectly however, I'm struggling with the rest of the routing now.
I can now navigate to http://localhost/user-1
However, I basically need to remove the /user/ part completely. When I'm editing / updating a page, I end up with it going to:
/users/user-1/edit
All works fine but it then redirects to"
/users/user-1/
I really need both of these to redirect to
http://localhost/user-1/edit
Thanks
Bob

You want:
resources :users, :path => '/'

I believe get ":id" => "users#show" will be much the same except you only allow HTTP GET. Hope this works.

At the bottom of your routes
match "/:id", :to => "users#show"
There is some side effects so be ready
to rewrite your routes you should specify its name:
match "/:id", :to => "users#show", :as => :user
or, as #Whirlwin pointed, better to use just GET request as default
get "/:id", :to => "users#show", :as => :user
So now you can call:
user_path(#user)

Related

Rails Routes Redirect To Blog On Subdomain

I have moved a blog from my main domain to a sub domain and want to redirect traffic that was directed at the original blog to the same post on the subdomain using Rails 5.1 routes and wildcards.
For example, my original address was https://www.dolgins.com/blog/2018/5/22/unique-hand-crafted-mosaic-jewelry-at-richard-dolgin-private-jeweler. Now, if someone enters this address, he/she would be redirected to https://blog.dolgins.com/blog/2018/5/22/unique-hand-crafted-mosaic-jewelry-at-richard-dolgin-private-jeweler.
Here is my current routes that pertain:
Rails.application.routes.draw do
get 'blog/*all' => redirect(subdomain: 'blog', path: '%{all}')
get "/blog" => redirect("https://blog.dolgins.com")
end
However, these routes redirect to http://blog.dolgins.com/2018/5/22/unique-hand-crafted-mosaic-jewelry-at-richard-dolgin-private-jeweler versus http://blog.dolgins.com/blog/2018/5/22/unique-hand-crafted-mosaic-jewelry-at-richard-dolgin-private-jeweler with the bold showing the difference.
Any ideas about what my routes should be?
Thank you!
You were really close
Rails.application.routes.draw do
get 'blog/*all' => redirect(subdomain: 'blog', path: '/blog/%{all}')
get "/blog" => redirect("https://blog.dolgins.com")
end

Rails Routing -- Adding Custom Route

I'm almost certain that someone has asked this question before, but I can't seem to hit on the right series of words to find it.
I have a resource, Games, with all of the normal resource-y paths. Create, Edit, etc.
I've created a new action within GamesController called json that I want to be able to access at mydomain.com/games/json but the routing keeps picking up 'json' as the ID and routing it to the 'show' action instead.
Presumably this is because of the default route:
match ':controller(/:action(/:id))'
I've tried a number of things, but no matter what I do it keeps routing to 'show.' I've been attempting to figure it out using this guide, but for someone that's pretty new to rails its quite a bit to take in and apply.
I'd like to say that for any controller /json would take you to the json action (instead of show with id 'json'), but I'd settle for having to specify it for every controller individually.
Any help is greatly appreciated. (Even if that's just pointing me to the already answered question.) In all cases I've been placing the route I'm attempting to create above the default route.
My routes:
root :to => 'home#index'
resources :events, :players, :sets, :matches, :characters, :videos, :games, :event_instances, :game_instances
resource :user_session
resource :account, :controller => "users"
resources :users
match '/login', :to => 'user_sessions#new', :as => 'login'
match '/logout', :to => 'user_sessions#destroy', :as => 'logout'
match '/register', :to => 'users#create', :as => 'register'
match '/games/json', :to => 'games#json', :as => 'gameList'
match ':controller(/:action(/:id))'
Ok so what you need to do is put your custom json route above your other resources routes and make it default like so:
get '/:controller/json(/:id)', action: 'json'
resources :events, :players, :sets, :matches, :characters, :videos, :games, :event_instances, :game_instances
...
Your confusion was linked to the way the routes are built and urls are parsed
Think of your routes.rb file as a set of consecutive filters to be applied to the url requested by the client.
If you put a default route above another it will catch all request that match the given pattern => this means that when you were adding all your resources routes above your json route, all urls matching the /#{resources}/:id pattern (and /games/json is one of them) were caught before they could reach the json custom route.
By putting your custom route above the others, you make it catch any request matching the pattern, that means in that case all requests with
/#{controller_name or resource_name)}/json(/:id)
NB:
I am not quite sure this is the best design pattern to use for your routes and I'd rather go with conventional REST routes with basic CRUD actions that would implement the respond_to pattern to answer specific json requests.
See docs for this: http://apidock.com/rails/ActionController/MimeResponds/InstanceMethods/respond_to
Adding such 'catch all' routes on top of all your resources may become risky when your app grows.
But you may have your reasons to go this way, in that case, I think my answer matches what you need.
resources :games do
collection do
get :json
end
end
if you also wanted to add an action that would take an :id path segment and return, say, json representation of a specific game, you'd do that with
resources :games do
collection do
get :json
end
member do
get :json
end
end
I'd add that when I was brand new to Rails (less than 1.5 years ago), the routing dsl was really hard for me to get my head around for some reason. But it's worth studying that guide, despite the fact that it's a bit overwhelming at first. Otherwise you'll end up with a bunch of match '/route/to/somewhere' => 'controller#action', :as => :some_helper, which ends up being a pain to read & maintain and will make it harder to have a consistent "grammar" for your urls.
Edit: looking at your now-posted routes file, the problem is that you declare the games/json route after the resources :games declaration. Route-matching precedence proceeds from the top of the file down, so the resourceful route for games matches first, and the specific route declared later is never checked. If you use the syntax above to make your json route a part of the resource declaration, this won't happen.

Devise logs users out after hitting certain routes

Here is my routes files:
Tubalr::Application.routes.draw do
devise_for :users
root :to => "application#index"
get "/player/:search_type/:search/:first_video" => "application#player"
get "/just/:artist_band.json" => "api#just"
get "/similar/:artist_band.json" => "api#similar"
get "/:username/favorites.json" => "api#userFavorites"
get "/just/:artist_band" => "application#index"
get "/similar/:artist_band" => "application#index"
get "/history" => "application#history"
get "/:username/favorites" => "favorites#init"
post "/check-favorites" => "favorites#check"
post "/favorites/add" => "favorites#add"
post "/favorites/remove" => "favorites#remove"
devise_scope :user do
get "/users/sign_out" => "devise/sessions#destroy"
end
end
The routes /history and the default /users/edit route for devise do not log the user out.
I'm not sure what other information to give, if theres something that would help debugging my problem, please let me know and I'll update the question.
The entire projects code can be found here: https://github.com/cjstewart88/Tubalr/tree/user_favorites
After digging around I finally ran into this:
https://github.com/plataformatec/devise/issues/913
It appears that the csrf token needs to be passed along with AJAX request, which my app is doing a good bit.

Rails 3: How do I route a controllers index and show actions to root while sending new/edit/destroy to /admin?

First off, I'm using rails 3.0.8 with friendly_id 3.2.1.1.
I'd like to be able to view the posts at website.com/:title, so drop the "/posts".
But I'd also like to have an /admin view. From there, a user should be able to create/edit/destroy posts. I already have a admin.html.erb view with links to various actions.
Right now my routes file look like:
MyApp::Application.routes.draw do
root :to => 'posts#index'
resources :posts
match "/:id" => "posts#show"
match "/admin" => "posts#admin"
end
This works for website.com/:title, but for website.com/admin I get an error:
Couldn't find Post with ID=admin
.... which makes sense. But I'm not sure how to solve this problem.
The rules are run through top to bottom. So put your admin rule on top of the resource definition.
If you put /admin first then it will work (as noted by cellcortex). You can also use :constraints if you can neatly separate your :id from 'admin'; for example, if your :id values are numeric, then something like this should work:
match '/:id' => 'posts#show', :constraints => { :id => /\d+/ }
match '/admin' => 'posts#admin'
In a simple case like yours, putting things in the right order will work fine. However, if your routing is more complicated, then the :constraints approach might work better and avoid a some confusion and chaos.
Use this
resource :posts, :path => '/'
with this all of your article will be directly under root
So in Posts Class you may add this:
def to_param
"#{id}-#{title.parameterize}"
end

Ruby on Rails: subdomain too powerful? how do I set this up the right way

routes:
match '/' => 'site_admin/admin#index'
resources :link_pages
resources :services
resource :user_session
resource :account, :controller => "users"
resources :password_resets
resources :users
resources :addresses
resources :info
match "/home", :to => 'info#home'
match "/register", :to => 'users#new'
root :to => 'info#home'
match ':controller(/:action(/:id(.:format)))'
so when I got to admin.lvh.me:3000/ it goes to site_admin/admin#index... which is great...
but when I take off the subdomain, and just have lvh.me:3000/ it goes to the same route....
how do I get admin to stay where it is. and no subdomain to go to my root page, as in my routes file?
Routes are parsed in order, so when you request / from any domain it finds "match '/'..." first and sends you to the specified page. Your subdomain isn't coming into play at all. You can use Request-based constraints to route based on subdomain:
http://guides.rubyonrails.org/routing.html#request-based-constraints
Not sure how subdomain factors into this at all. Perhaps you're confusing subdomain with route namespacing (http://edgeguides.rubyonrails.org/routing.html#controller-namespaces-and-routing)?
match '/' => 'site_admin/admin#index'
Is being selected over
root :to => 'info#home'
Because it's defined first in the routes file. They're ostensibly the same thing.
Yes #Cory is right. Above both statements are similar and first defined route is considered every time. If you change admin route to
match '/admin' => 'site_admin/admin#index'
then it does make sense... What say??
or else, using the following code you can determine your URL conditionally:
request.subdomains(0).first will give you the subdomain value- either admin or blank. But it will go to any one controller action only which is defined first in route.rb file.
Then from that action using subdomain, you can decide where to re-direct it- either to admin panel or home page...

Resources