Ruby On Rails Overlapping Routes - ruby-on-rails

I'm rebuilding/redesigning a site in Rails that's currently in production using Magento. To ensure that I don't lower my seo rankings I am keeping my URI's the same. I am facing an optimization issue with this because the current site doesn't have subdirectories. With that said, the products are under the root directory of the site, the reviews are under the root directory of the site, and all the other content pages are under the root directory of the site.
for example a product might be at
www.example.com/some-product-name
and a review could be at
www.example.com/some-review-name
rails obviously uses routes and my first guess was to make a route that looks like this:
get '/:uri_identifier', to: 'pages#find_page'
This works fine, but with 50k products to query through and 5k reviews along with another 200 different content pages, this creates an optimization issue since this controller method becomes a catch all to figure out which page it should render based on
params[:uri_identifier]
The uri's don't have any kind of form either so filtering them with an if statement to avoid large amounts of queries isn't really feasible. My idea was to create routes specific for the reviews and add them in routes.erb above the route
get '/:uri_identifier', to: 'pages#find_page'
but I'm still going to have to create close to 5k routes to pull this off. I did try this and it worked, but I'm not real sure what is the best way to approach this issue to ensure that I use the least amount of resources.

There are several patterns for solving this kind of problems in rails. One of which is slug constraint. Use this resources they help with the concept of using slugs and refactoring large rails routes
http://blog.arkency.com/2014/01/short-urls-for-every-route-in-your-rails-app/
http://code-worrier.com/blog/custom-slugs-in-rails/
Refactoring a large routes.rb file in rails 4

Related

How can I omit controllers for two models in rails 3 routes?

I'm building a rails3 application and at the moment I have the following line in my routes.rb file:
get "/:id" => 'tapes#show'
In other words, you can show a Tape using website.com/tapes/1 and also by using website.com/1
(I am also using friendly_id gem so the user sees in fact a friendly URL in the form of website.com/tapename)
Now, what I would like to achieve is to do the same thing for Users pages. So instead of showing a User page using website.com/users/alex I want to be able to also use website.com/alex.
Is there a way to implement this 'users' logic in routes.rb together with the existing 'tapes' rule and somehow set a priority?
So if someone accesses website.com/alex my app would search if there is a User record with id 'alex' and if none is found then look for a Tape with id 'alex'.
Could I use some kind of Advanced Constraints in routes?
Any ideas?
Many thanks for the help,
Alex
Rails would have no way to determine which controller you were trying to access. The only way that this would be possible, is if either:
you could determine which model it would resolve to based upon some regular expression on the name.
or
You knew that user names and tape names never conflicted, and were willing to suffer the cost of hitting the database to resolve the correct controller.
This is probably a bad idea for a number of reasons, it would have performance implications, it also doesn't conform to RESTful principles, and it would probably be confusing to users.

Mass 301 redirects in Rails 3

We've built up thousands of product urls while using Magento as our cart application and these URLs are not at all intuitive or that SEO friendly, despite having built up our search rankings on them.
We are transitioning to Rails 3 (with Spree as our cart) and would like to clean up our URLs. I'm wondering what's the cleanest way to handle potentially thousands of 301 redirects in Rails? Hard coding that many in routes.rb does not seem sane.
Possibly pertinent info:
We're tied to using Heroku for at least the next few months.
The best way to do this would be with a route glob. In routes.rb:
match 'products/*product_url' => 'products#redirect_to_real_product'
As long as this match is underneath all your other product matching, it'll connect to ProductsController#redirect_to_real_product with a helpful param[:product_url] that you can perform scanning and lookup on to redirect the user to the correct product.

Is it OK to create meaningless singleton resources just to stay RESTful? Rails

In the process of making an ebook, users have to edit its content, edit its metadata, choose marketing options, (such as pricing and distribution) and publish.
I started to put each everything inside the Book resource (contents, metadata, marketing options etc)
Then each step of the process (contents, metadata, marketing) is an action inside BooksController.
But Books started to grow a lot in terms of attributes and actions.
I'm wondering if it is better to force RESTfulness by creating singleton resources, each associated to their respective book.
The routes would be:
/book/12/content/edit
/book/12/metadata/edit
/book/12/marketing/edit
This seems more elegant, as each of these "resources" are RESTful and have few attributes each. But the resources are not objects (Marketings?).
Do you thing it's OK to create meaningless resources just to be RESTful and keep code in order?
Is there a better way to group similar attributes than create resources out of them? Thanks.
I'm porting a large PHP application to Rails and we have a fair few "ad-hoc"resources, such as admins have the ability to log in as another user with their permission, in order to correct issues etc. I would always complain that features such as logging in as other users should not be bundled into a huge monolithic AdminController as actions loginAsUser and logOutOfUserAccount. In our Rails app we try to visualize as much as we can in terms of resources, so using the example I just gave, we have an Admin namespace, under which there is a UsersController (/admin/users/:id) and as a sub-resource of users, we have a UserOverride resource (/admin/users/:user_id/override)... it feels really logical that we just POST and DELETE to this resource.
So getting back to your example, yes, I think you should break those sections down into separate resources. It certainly seems like BookContent should be a sub-resource of Book, and MarketingOptions too.
resources :books do
resource :content
resources :marketing_options
end
etc
This is both nicer to work with (more modular) and easier to visualize just from looking at the routes alone. You also get the benefit of really predictable path helpers:
<%= link_to("Marketing Options", book_marketing_options_path(#book)) %>
You can't try to force every conceivable route into a RESTful resource ideology though... if it feels like it's forced, then it probably is.
There's a decent blog post I wanted to link to that (despite some poor grammar) actually does a pretty good job of showing you how to think about your application in terms of resources... I can't find it though. I'll add a comment if/when I do.
EDIT | Just re-reading your original question and wanted to clarify: resource != row in database. A resource is anything you can conceive as a "thing"... I know that's a very broad statement, but just like an Object in OOP doesn't have to represent something concrete/material, nor does a resource in a RESTful design.

SEO for Rails site, now or later?

My freelance web developer is developing a site on Ruby on Rails. Currently the URL structure is
http://abc.com/all?ID=category
Example:
http://abc.com/all?3=CatA
I requested him to structure the URL according to categories, such as
http://abc.com/CatA/3-page-title
but he refused cos it was too much work and cost involved as he is using the same model for Category A, Category B... I thought the URL structure that he is using is messy and not search engine friendly.
My question is, should I add cost to let him do a better structured URL I requested, or should I let the project finish, then do it in the next iteration?
I'm worried that if I do it in the next iteration, all the previous URLs structured in the old way will be purged and when sites that refer to it will show a 404 error. It's like I have to rebuild the site ranking all over again.
Any other solutions for me? Is that any way to redirect old URLs to new URLs automatically in Rails?
The way your developer is proposing to compose the URLs would be considered something of an anti-pattern is Rails. What you are looking for is close to what Rails does out-of-the-box when using RESTful resource routing, admittedly, I'm guessing as to how CatA and page-title are related to each other. A RESTful Rails route might look like this (using your example):
http://abc.com/categories/3-CatA/pages/10-page-tite
If he really is using Rails, and he knows what he's doing, then there should be no cost at all to converting to what you want. It just needs the correct routes defined and then a to_param override in your models to get the nice SEO friendly identifiers.

Rails routes and site performance

Is there a direct correlation on site speed with the number of namespaces / routes in the routes.rb file of a Rails Application?
I am handling a fairly large application with more than 30 disparate models/entities and most of these resources have their own routes.
the number of routes will affect the memory overhead - it's why rails no longer defines formatted routes out the box: http://ryandaigle.com/articles/2008/11/27/what-s-new-in-edge-rails-no-more-formatted-routes
It's not unusual to have 30 or so routes though
As for whether or not this will affect the speed of your app, it's difficult to say - are you using metric-fu or anything like that?
I don't have a citation† but DHH recently said that 37signals' Highrise application has thousands of routes, so it is possible to scale the routes if you have a big enough box to run your application on.
† I think it may have been during his recent RailsConf keynote, when he was talking about the new router API in Rails 3.

Resources