| Path: | base_record.rb |
| Last Update: | Tue Aug 16 23:54:41 GMT Standard Time 2005 |
Overrides ActiveRecord::Base to provide support for table_sql. This allows the table name in a query to be replaced with a subquery, essentially simulating a view within ActiveRecord.
Currently, this has only been tested on MySQL 4.1 and Ruby on Rails 0.13.1.
This defines two new class methods set_table_sql and set_table_sql_columns. Both must be used to make a BaseRecord subclass use table_sql. Usually, set_primary_key will have to be called as well (if the primary key of the view is not called id). For example, a ParentDetail class could be defined as:
belongs_to :parent
set_table_sql(<<-TABLE_SQL
SELECT
parents.id parent_id,
SUM(children.attribute) attrib_sum
FROM
parents
INNER JOIN children ON parents.id = children.parent_id
GROUP BY parents.id
TABLE_SQL
)
set_table_sql_columns([
ActiveRecord::ConnectionAdapters::Column.new('parent_id', nil, 'bigint'),
ActiveRecord::ConnectionAdapters::Column.new('attrib_sum', nil, 'bigint')])
set_primary_key('parent_id')
Parent, which should also inherit from BaseRecord, could then be defined as:
has_many :children has_one :parent_detail
You can then perform eager loading finds like the following:
Parent.find(:all, :include => [:parent_detail, other includes...])
This find will produce SQL like the following:
SELECT
parents.id,
other parents fields...,
parent_details.parent_id,
parent_details.attrib_sum,
FROM
parents
LEFT OUTER JOIN (<table sql for ParentDetail>) parent_details ON parent_details.parent_id = parents.id
To upgrade to future versions of ActiveRecord (this was based on RoR 0.13.1, ActiveRecord 1.11.1):
* Check for any changes to the overridden methods and update as necessary:
* columns
* construct_finder_sql
* construct_finder_sql_with_included_associations
* association_join
* class_name_of_active_record_descendant
* attributes_from_column_definition
* Check for any new methods that access connection.columns directly and
override to call table_sql_columns instead.