Creating custom routes in Rails for SEO - ruby-on-rails

I am following a tutorial on seo in rails and i got my routes.rb like this
resources :blogs,only: [:new,:index]
get "/blogs/:id", to: redirect("/%{id}")
resources :blogs,:path=>'',except:[:new,:index]
everything should be fine but when i create a blog it doesn't show error and doesn't create a blog too.it just redirects to blogs_path.
what am i doing wrong?
it works fine like
resources :blogs
but then i would lose the benefits of the other code. and i need them for my SEO.

after a day of sleeping on it I found that i had to mention the :create and :update actions to my routes it'll be like this
resources :blogs,only: [:new,:index,:create,:update]
get "/blogs/:id", to: redirect("/%{id}")
resources :blogs,:path=>'',except:[:new,:index]

Related

Customize nested routes for a cleaner URL in Rails?

I am working on a website and I am trying to change how the URL looks for the users.
As I have all my resources nested, I struggle a lot to do what I want.
At the moment, here are my routes
resources :folders do
resources :portfolio_photos
end
I've changed it to this, which works for the folders index.
resources :folders, except: [:index] do
resources :portfolio_photos
end
get '/photos', to: 'folders#index'
The only problem is that I also want the "portfolio_photos" url to look like this
/photos/:id/portfolio_photos
(and I don't want to change the name of my model).
I've tried that:
get '/photos/:id/portfolio_photos', to: 'portfolio_photos#index'
but it is not working.
Even better would be to get a completely custom URL looking like that on the surface : www.xxxx.com/portfolio_photos
even if everything is nested in the backend.
Is there a way to change how the url looks without touching the whole backend?
Thanks a lot for your help!
After 2 hours of researches, I've found this:
resources :folders, :path => 'photos' do
resources :portfolio_photos
end
Works perfectly and I just had to change the routes file!
Posting it as it will maybe help someone :)
Thanks everyone

How to stop Rails route preempting another

I am working on an API for a mobile app. I am running into a problem where one of my routes is preempting another. The two routes are:
api_vocabs_all GET /api/vocabs/all(.:format) api/vocabs#all
api_vocab GET /api/vocabs/:id(.:format) api/vocabs#show
Whenever I navigate to "api/vocabs/all" Rails sends the request to the show method with the id = all. Is there a way around this?
Update: Looking at my code again I noticed that while the above doesn't work the non-api version does work. Do I need to put my route inside the namespace?
vocabs_all GET /vocabs/all(.:format) vocabs#all
vocab GET /vocabs/:id(.:format) vocabs#show
Below are all my routes from routes.rb
namespace :api do
resources :vocabs
end
get 'vocabs/all' => 'vocabs#all'
get 'api/vocabs/all' => 'api/vocabs#all'
resources :vocabs
Converting my comment into an answer. Put api/vocabs/all above the namespace :api. Remember that your routing file should be ordered from most specific to least specific.
get 'api/vocabs/all' => 'api/vocabs#all'
namespace :api do
resources :vocabs
end
get 'vocabs/all' => 'vocabs#all'
resources :vocabs

Changing the route from posts/article to blog/article in rails

I'm in trouble with routes in Rails. I've been trying to get a path like: home/blog/title-article but the closes I get is: home/blog/posts/title-article
I've tried with namespace, scope and one by one with get 'blog' => 'posts#blablabla', but I get errors like UrlGenerationError or NameError every time I change the paths. I've read the official guide and some answers in this forum, but I'm getting more confused hehe
In my last try I generated a controller Blog and a scaffold Post. The output of rake routes is: http://i.stack.imgur.com/gdfPc.png
routes.rb
Rails.application.routes.draw do
scope :blog do
resources :posts
end
get 'blog' => 'blog#index'
root 'pages#index'
...
Thank you!
Now my routes are like: http://i.stack.imgur.com/cKsFG.png
Thank you!
Not sure its what you expect but try:
resources :posts, path: 'blog'
Feels weird though.
Btw, I guess you have the errors due to url helpers.
use rake routes to check the existing routes and the related url helpers.
Doc lives here

Getting no route matches on the show action

I'm trying to use the path from the following route, here is what it's like in rake routes
chapter GET /chapters/:id(.:format) {:action=>"show", :controller=>"chapters"}
chapter_path creates a link to /chapters/x which is correct but I get the routing error when trying to access it.
No route matches {:controller=>"chapters"}`
this is my routes (I am using shallow routing to create a books_chapters and book_chapters_new paths.
resources :books do
resources :chapters, :shallow => true
end
when I test the route with rake routes, I get books_chapters, books_chapters_new, chapters and books, so I don't know what's wrong.
when i remove :shallow => true, i can access /books/1/chapters/6 but I just want it to be /chapters/6
this is what my terminal looks like
so /chapters/id and /chapters/id/edit should be working fine.
I've restarted the server with touch tmp/restart.txt and ran rails s to see if the routes worked there too and rake routes is giving me acceptable routes, but they don't work for me.
Are you supplying the parameter for the path helper, something like
chapter_path(#chapter)
I couldn't figure out how to get :shallow routes to work, and there isn't an example on how to use :shallow in the rails guide so, instead I have to just use nested routes like so
resources :books do
resources :chapters
end
now this means the something like chapters_url or chapters_path won't work.
So I have to do something like this everywhere
book_chapter_url(#chapter.book, #chapter)
or
edit_book_chapter_path(#chapter.book, #chapter)
It works but there's a bit of code smell because I use #chapter twice and the whole url should be able to resolve just through the chapter id instead.

Do you have to mess with Rails's "routes.rb" file?

I never touch routes.rb beyond calling map.root to set a default route. I've always been content to use URLs of the form...
/controller/action/perhaps_an_id
and it works fine.
Does this make me a bad person? Am I missing out on something totally awesome?
What if I try to adopt RESTful design? Would that mean I have to edit routes.rb or could I continue to pleasantly ignore it?
(I tried to read up on this topic in The Rails Way but it was unbearable.)
If you generate your resources with the default scaffolding then it will even include the restful routing for you in routes.rb.
If you're not using the scaffolding then the reason that it's working is because of the default routes at the bottom by default:
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
I've been following that it's best practice to remove these for production applications and instead make sure that only the resources that need to be exposed are exposed. With Rails 2.2 you can even limit the RESTful methods from map.resources by:
map.resources :posts, :only => [:index, :show]
map.resources :comments, :except => [:edit]
There's also tons of cool things you can do with nested resources, named routes, etc. They have a lot of examples in the docs (http://www.railsbrain.com/api/rails-2.2.2/doc/index.html?a=M000255&name=resources)
You may also want to make custom named routes for your marketing department (eg: mycoolsite.com/free-trial) that go off to specific controllers and actions, etc.
Ryan Bates has a series of screencasts that go over some of the neat things you can do with routes: http://railscasts.com/tags/14
Not having switched to RESTful design does not make you a bad person and if you feel no need to change keep writing your apps the 1.x way.
The majority of Rails developers has adopted REST and seems to be very happy about it. I don't think there is a need here to repeat all pro REST arguments.
You do need to add one line per resource to your routes file such as:
map.resources :posts
If you were to go RESTful, yes you would have to edit routes.rb and add your resources like,
map.resources :your_resource
or if you have nested resources,
map.resources :people do |person|
person.resources :ideas do |idea|
ideas.resources :bad_ones
end
end

Resources