Rails routes and site performance - ruby-on-rails

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.

Related

Ruby On Rails Overlapping Routes

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

Is this Incorrect Usage of Rails Routing?

a couple days ago i started a project- i'm not using restful routes and my whole file looks like this match '/a/b' => 'a#b' over and over. Are these kind of routes considered incorrect or bad?
This is considered bad practice. Instead you should use resource or resources liberally and do your best to follow the seven RESTful actions. Your best bet is to read The Ruby on Rails Routing Guide as it provides many great examples!
It would be great if you could fit your routing into some kind of RESTful action, but if not, at least clump your controllers together in blocks. I doubt all of your controllers will just have a single route? If so, consider Sinatra, unless you are just playing around, then this conversation is pointless. If you are not using this in a real production app, your real question should be "Where do i learn how to use routing effectively"?

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.

Doing a Rails Restful Implementation or Not?

I am pondering on using a Restful implementation in Rails. I'm asking myself if it's the way to go.
Should I always go for a Restful implementation or not?
I think there really isn't much other option as far as Rails goes. You would just be fighting against all the design decisions and sensible defaults that Rails, as a framework, has already made for you.
Think about all the provided shortcuts for routing, pathing, forms, etc. I think you would end up just spending more time/effort on a non-RESTful implementation.
The first thing to sort out is what REST really means. Fundamentally it is about utilizing HTTP efficiently and correctly. That is, GET requests don't modify anything, PUT requests are idempotent, etc. The notion of uniquely identified resources just sort of falls out of this optimal usage of HTTP. The beauty of REST is that you gain the maximum programmatic benefit out of HTTP, making things like caching, proxying, and automatic retrying able to work fairly well without any knowledge of the application whatsoever. Dare Obasanjo wrote a nice rant on the topic of REST misunderstanding. This contrasts heavily to something like SOAP where you have an heavyweight envelope format that uses HTTP as nothing more than a glorified transport layer.
Now when it comes to Rails REST there is a whole nother thing going on, and that is Rails' convention over configuration. Rails REST is just a thin baked-in layer of tooling to make it easy to define CRUD operations on resources you define. Note that these resources don't need to correspond to ActiveRecord models, and certainly using Rails resource routing is not a pre-requisite for designing a RESTful application. What Rails gives you is an extremely handy default for dealing with things that fit the model of a CRUDable resource, however you shouldn't hesitate to define additional methods on top of resources, or to forego resources altogether if you have pages that don't really seem like resources (eg. reports).
The bottom line to keep in mind is that it's not one or the other. Rails RESTful helpers are using the same primitives that have always been in Rails. You can use both together and they jive nicely.

Best practice for structuring a 'large' Rails app

My question here is seeking best practice, general advice and insight, rather than a solution to a specific problem.
I am in the early stages of planning out a Rails project which I consider fairly large. At its simplest level it offers a cookie-cutter CMS to the target users. So users sign up and choose a subdomain and are given a pretty basic website with CMS.
Therefore the entire app has about 4 different 'sides' to it:
A sales website selling the product to end users - www.myapp.com
A central admin area where staff can log in and manage accounts etc - www.myapp.com/superadmin
The users' own websites - subdomain.myapp.com
The users' admin area/CMS - subdomain.myapp.com/admin
So really what I'm looking for is best practice for structuring the app. i.e. should it all be rolled into one huge application or should it be split over 2 (or more) smaller apps?
If deployed as one application, I can see issues surrounding routing as both the sales website and the users' websites will need a root path set, plus I would not want the routes I set for the sales website being accessible through the users' websites. Can anything be done either within Rails or at Apache level (mod rewrites ?) to ensure no mixup of routes?
If split over 2 or more applications, how do you get the applications sharing the same database? Is that even a good idea? Are there any benefits from splitting the application (like isolating problems in one area of the app, rather than bringing everything down)?
I realise this post raises quite a few different questions, but appreciate any advice and insight you can give me.
I believe the benefits of isolating your concerns into separate apps outweigh the costs. I would probably start off with just 2 apps (one for the main site and superadmin, one for the client sites and admins), accessing the same database, but you could do 4.
The downside is you don't really have isolation since all your apps are tied to one database. You will eventually run into scaling problems with your database, but starting off simple with one database will get you launched. One strategy for scaling later would be to add a slave db that the client site and main site apps use, while the admin apps use the master db. This along with a TON of caching will get you pretty far.
There is nothing wrong with having multiple rails apps access one db, however you will need a way to share common code across your apps. Your models for the most part. I've done this before by tossing all my models in a plugin that I share as a sub-module in git or as an external in svn. Having separate apps will make each app smaller and easier to maintain.
However, where do you keep your migrations? Where do you test your models? I would opt for the superadmin app. Also, you make a change to a model or the schema, and now you have to check 2-4 apps and make sure they still work!
Better isolation, separate db's and inter-app communication through web APIs (SOA) and you don't have to worry about that. SOA I think is the way to go after a certain point, but SOA might be premature when you first start out.
At any rate, having separate apps sets you up for SOA but you don't have to jump beyond a single db to start.
I would bundle this all into the same app because you won't be duplicating the classes (models, plugins, etc.) across all the apps. Also: running 4 apps means that you'll have 4 processes all consuming memory due to the 4 separate Rails stacks they have loaded.
Compiling it into one application eliminates this issue. For the issue between the sales site and the users site having to have different roots that can be solved, as mentioned earlier, by subdomain_fu. Let me expand with some sample code from an application I have:
map.with_options :conditions => {:subdomain => 'logs'} do |admin|
admin.resources :channels do |channel|
channel.resources :logs
end
map.root :channels
map.connect ':id', :controller => "channels", :action => "show"
end
As we see here, the :conditions for the with_options method sets :subdomain to be logs which means that anything coming in to logs.mysite.com will fufill these conditions and therefore be routed this way.
Now further on in this routing file I have everything else wrapped up in a similar block:
map.with_options :conditions => {:subdomain => nil} do |admin|
# shebang!
end
Everything going to mysite.com will go to these routes.
Lastly, compiling it all into one mega-super-hyper-app will eliminate the database-sharing issues.
The biggest issue I see with separating into several apps is that you lose flexibility. What happens if, in the future, a previously administrative task (eg. uploading a type of file) becomes a "user task"? You would have to be moving code from one application to the other.
I'd keep everything on single application - and use roles for filtering what each user can see and do. It might be a bit more difficult at the begining, but it pays up in the near future.
Have a look at authorization frameworks, such as declarative_authorization or cancan.
Well, since nobody else has spoken up, I'd encourage you to do some reading on Service-Oriented Architecture. The book Enterprise Rails by Dan Chak has some great material on this, and you can read a lot of it through Google Books. Try chapter 13, here. I think it'll put you on the right track.
I see the kind of problem you are facing is, trying to build an application which will have various sub domains, so account_manager a plugin can solve your problem.
also if your application is large enough to maintain than splitting them in two or three would be good idea, with restfull resources you can make your applications talk to each other and so.
while if you are thinking of having them under one database, thats quite simple in rails using the establish_connection.
I think you can split the application in three to four different applications where set of clusters will handle each applications request, so the speed will be good. also you can bundle similar kind of functionality in one app to make sure maintaining them is easy.
http://www.railslodge.com/plugins/1113-subdomain-fu
As far as my research has taken me, most companies at high scale would opt for SOA with multiple databases. Here are links to some information on how Linked In and EBay think about this. And to echo PreciousBodilyFluids, I highly recommend the Enterprise Rails book by Dan Chak.

Resources