Here are a few additional notes regarding my experiences with Ruby on Rails. Although there is veritable dearth of information on these topics, the difficulty as ever lies in having a single consolidated reference for these issues. At best, documentation on the web is complete with examples and thoughtful explanations; at worst, it is completely misleading and full of uninformed assumptions.
Required database.yml parameter : database
The database.yml file requires the database : parameter in order to establish a valid connection to the database for a given user. This parameter was not present in earlier versions of the database.yml configuration file. See below for more details documentation regarding the PostgreSQL connection adapter parameters.
Database Adapters: pg versus postgres
At the time of writing this (against rails 2.2.2), there still seems to be a preference in the Rails framework for the pg driver over the postgres driver. Without the pg driver installed, the following error is displayed to the user :
/Library/Ruby/Gems/1.8/gems/activerecord-2.2.2/lib/active_record/connection_adapters/abstract/connection_specification.rb:74:in `establish_connection': Please install the postgresql adapter: `gem install activerecord-postgresql-adapter` (no such file to load -- pg) (RuntimeError)
from /Library/Ruby/Gems/1.8/gems/activerecord-2.2.2/lib/active_record/connection_adapters/abstract/connection_specification.rb:58:in `establish_connection'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.2.2/lib/active_record/connection_adapters/abstract/connection_specification.rb:53:in `establish_connection'
from /Library/Ruby/Gems/1.8/gems/rails-2.2.2/lib/initializer.rb:392:in `initialize_database'
from /Library/Ruby/Gems/1.8/gems/rails-2.2.2/lib/initializer.rb:139:in `process'
from /Library/Ruby/Gems/1.8/gems/rails-2.2.2/lib/initializer.rb:112:in `send'
from /Library/Ruby/Gems/1.8/gems/rails-2.2.2/lib/initializer.rb:112:in `run'
from /Users/mel/Documents/Workspace/vuespace/src/config/environment.rb:13
from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `require'
from /Library/Ruby/Gems/1.8/gems/rails-2.2.2/lib/commands/generate.rb:1
from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `require'
from ./script/generate:3
aleph:src mel$ gem install activerecord-postgresql-adapter
ERROR: could not find gem activerecord-postgresql-adapter locally or in a repository
aleph:src mel$ sudo gem install activerecord-postgresql-adapter
Password:
ERROR: could not find gem activerecord-postgresql-adapter locally or in a repository
aleph:src mel$ sudo gem install activerecord-postgresql-adapter
ERROR: could not find gem activerecord-postgresql-adapter locally or in a repository
aleph:src mel$ sudo gem -r install activerecord-postgresql-adapter
ERROR: Invalid option: -r. See 'gem --help'.
aleph:src mel$ sudo gem install -r activerecord-postgresql-adapter
ERROR: could not find gem activerecord-postgresql-adapter locally or in a repository
To install the correct the correct pg gem, use the following command:
# sudo env ARCHFLAGS="-arch i386" gem install pg
There seems to be a version difference between the two difference postgres adapeters : pg (0.7.9.2008.10.13) versus postgres (0.7.9.2008.01.28). Only time will tell if this will lead to framework incompatibilities.
ActiveRecord
To use the scaffolding in any meaningful manner requires a clear object model that can be used to represent system objects. The ActiveRecord::Migration class provides detailed usage information that is required to generate these classes and the associated database types. However, details such as the rails type to database type mappings are not easily found in Rails API. The following links highlight the most important features of ActiveRecord objects which will hopefully allow more informed use of this fundamental Rails object.
Object Associations
As ever, the initial challenge when creating an application is to create an object model that reflects the system being designed without imposing unnecessary limitations. There are a number of relationships that can be modeled through Rails, but it is important to understand both the usage and limitation of these mechanisms.
- Rails only supports Single Table Inheritance - By default only Single Table inheritance is supported by Rails. Essentially, different subclasses are represented by a
:type field in the database table. To avoid confusion, treat type as a Rails keyword an only use it when you want to model Inheritance.
- Polymorphism is supported through the
:has_many :has_one/ :as mechanism - common functionality can be shared amongst objects by implementing an interface. This requires the implementing object to have interface_id:integer and interface_type:string columns within their database models.
- The difference between
:has_one and :belongs_to is largely where the foreign key resides. - The :belongs_to implementation should have the corresponding foreign key to the referenced object.
- Many-to-many relationships can be modeled in a number of ways. Direct relationships can be modeled using
has_and_belongs_to_many. If the association needs to be manipulated independently, the has_many :through relationship will do provided a join table is created to associate the two models.
- Secondary associations using
:through. Both the has_one and has_many associations support secondary references through intermediate objects.
Object Hierarchies
There are built-in mechanisms with Rails to model ordered lists, trees, and hierarchies.
:act_as_list - allows a collection of object to function as an ordered list. This requires a position column within the model.
:act_as_tree - allows a collection to behave as a tree. Requires the parent_id column within the model.
:act_as_nested_set - allows a collection to behave as a hierarchy. The advantage over :act_as_tree is that individual nodes can be retrieved with their dependent objects. This model requires the use of the following columns : parent_id, lft, rgt.
Validations
Data sanitation is paramount to preventing a whole host of database injection attacks. Always assume that any publicly submitted data can be used to compromise the system. To mitigate these types of attacks, ActiveRecord supports validation of conditions and fields (see above). It is highly recommended that validations be exercised in the testing framework to ensure their proper functioning.