Revisited rails and the ruby after a few years to implement Keygames Network, and found it extremely productive. Why?
High level view of a software project
Doing a new software project incorporates doing the following tasks:
- Idea\ Think about and spec the idea, provide the rationale behind the idea and prove design is valid.
- Selecting open source components\ Select and look into the different components to base the implementation on. Look into the code-base, read the forums to get an idea on the quality of those components.
- Implementation\ start incremental implementation of idea based on components. Every subcomponent will have a test-suite.
- Dependency management\ put all components into a dependency manager, like the Bundler and RVM combo, to make sure all component versions can be included and are documented. This will speed up further development with other developers since they will be able to get up and running quickly. And this process will ease deployment.
- Deployment\ automate the deployment procedure. Spend some time on this since this will be a big time saver in the future. (Capistrano)
Rails, and the extremely productive ruby community provide excellent tools to handle all these phases of the development process.
Convention to ease the burden on human memory
It's a well known fact that most humans, ranging in intelligence can hold only 7 to 10 items simultaneous in memory. This limitation in cognition explains why we as humans structure everything in layers, often every layer consists of those 7 or 10 elements. Think of how a business is organised, how a text-book is divided into chapters, or how the law of a country is divided.
When building software, one of the challenges is handling complexity in a way you and the other people working on a project can manage this complexity. We have different techniques to do this. Modularisation, object oriented designs, functional designs, and convention. Rails uses convention extensively, it is one of its key features and part of the marketing behind it: "Convention over configuration".
The big plus of using convention is that one only has to keep the logical relations into memory. All derived elements can be generated from the naming of the defined root elements in combination with the logical relations.
Programmers, which (in my view) essentially means, organisers of information or complexity, develop a special skill for remembering methods. The "how" does one arrive to a specific goal. Facts are of less importance, structures are.
In rails a simple application reflects the naming and relations of the model throughout the system. This makes naming very consistent and predictable.
And as we all know consistency and predictability are measures of quality in software design, how this is implemented will follow.
One abstract view of Rails application
Most dynamic web-applications provide an interface to manipulate a model and provide a certain view to the data stored in the model. These views are controlled by a controller. This is the standard M(odel) V(iew) C(ontroller) paradigm. Rails is a certain implementation of this paradigm.
One could state that a Model (orders) is a resource which is manipulated by a view/controller combination. Rails provide a standard way of managing a resource using the following actions:
- list
- create
- edit
- delete
- show
Most controllers will implement one or more of these five and some more complicated actions or specified actions to change state of the specified member or collection of the resource. This is the called CRUD.
The end-user will navigate the dynamic web-app using links. Which will point to screens to either View, List, or Manipulate state.
How is it implemented
Rails makes it easy to create web applications which more or less conform to the abstract view presented above. The normal method of working goes like this.
One defines a model, one continues to define controllers and routes. From within these definitions the rails system generates url functions which is a specific combination of the model names.
A very simple model example:
class Shop < ActiveRecord::Base
has_many :orders
end
class Order < ActiveRecord::Base
belongs_to :shop
end
A simple resource_full route definition:
resources :shops do
resources :orders
end
Will generate:
shop_orders GET /shops/:shop_id/orders(.:format) {:action=>"index", :controller=>"orders"}
POST /shops/:shop_id/orders(.:format) {:action=>"create", :controller=>"orders"}
new_shop_order GET /shops/:shop_id/orders/new(.:format) {:action=>"new", :controller=>"orders"}
edit_shop_order GET /shops/:shop_id/orders/:id/edit(.:format) {:action=>"edit", :controller=>"orders"}
shop_order GET /shops/:shop_id/orders/:id(.:format) {:action=>"show", :controller=>"orders"}
PUT /shops/:shop_id/orders/:id(.:format) {:action=>"update", :controller=>"orders"}
DELETE /shops/:shop_id/orders/:id(.:format) {:action=>"destroy", :controller=>"orders"}
shops GET /shops(.:format) {:action=>"index", :controller=>"shops"}
POST /shops(.:format) {:action=>"create", :controller=>"shops"}
new_shop GET /shops/new(.:format) {:action=>"new", :controller=>"shops"}
edit_shop GET /shops/:id/edit(.:format) {:action=>"edit", :controller=>"shops"}
shop GET /shops/:id(.:format) {:action=>"show", :controller=>"shops"}
PUT /shops/:id(.:format) {:action=>"update", :controller=>"shops"}
As one can see in this simple example the model is reflected in the routes and in the generated url functions using linguistic functions. This was a new technique invented by Rails.
Actions
As you can see above every resource route generates routes to 4 standardised actions inside the targeted controller. Conforming CRUD. Which one could split up in 2 categories. Actions manipulating the collection of the resource, and actions which manipulate a member of the collection.
* collection -> shop\_orders
* index
* create
* new -> new\_shop\_order
* member
* edit -> edit\_shop\_order
* show -> shop\_order
* update
* destroy
Notice the pluralization and singularization of the different pars and how the relations as defined in the data-model is reflected in the routes.
More to come
I will specify more functionality in the future. Models and relations, and more on controllers.