README.md in dbview_cti-0.0.3 vs README.md in dbview_cti-0.1.0
- old
+ new
@@ -2,11 +2,12 @@
[![Build Status](https://travis-ci.org/mvdamme/dbview_cti.png)](https://travis-ci.org/mvdamme/dbview_cti)
This gem implements [Class Table Inheritance](http://martinfowler.com/eaaCatalog/classTableInheritance.html) (CTI)
for Rails, as an alternative to Single Table Inheritance (STI). The implementation is based on database views.
-Currently, only PostgreSQL (version >= 9.1) is supported. The gem works for both Rails 3.2 and Rails 4 apps.
+Currently, only PostgreSQL (version >= 9.1) is supported. The gem works for both Rails 3.2 and Rails 4 apps, and on
+MRI (>= 1.9.3), Rubinius and JRuby in 1.9 mode (due to some issues JRuby is not included in the travis tests, though).
## Installation
Add the following to your Gemfile:
@@ -140,10 +141,45 @@
1.9.3-p448 :005 > c.save!
=> true
Note that Car has all attributes of the vehicles, motor_vehicles and cars tables combined. When saving, the attributes are stored in their corresponding tables.
+## Initializer
+
+When running the migrations and for some of the functionality (see e.g. the `convert_to` and `specialize` methods below),
+it is important that each class knows about the full class hierarchy. This is taken care of automatically when a class
+is loaded. However, in order to have full class hierarchy information all classes in the hierarchy have to be loaded,
+which is not necessarily the case since rails lazy-loads classes (e.g. in development mode).
+Therefore, we have to force loading of all classes by referencing the leaf-classes in the hierarchy in an initializer.
+
+For the example given above the leaf classes are Car and MotorCycle, so we put the following in an initializer (e.g. in
+`config/initializers/dbview_cti.rb`):
+
+```ruby
+# Force loading of all classes in the CTI hierachy by referencing the leaf classes here
+Car
+MotorCycle
+```
+
+In development mode, Rails reloads files as you modify them. If a file in the class hierarchy is modified, all classes
+have to be reloaded, otherwise methods such as `specialize` and `convert_to` (see below) will no longer work correctly.
+To make sure the whole hierarchy is reloaded at every request (in development) we can modify the above initializer to:
+
+```ruby
+# this block makes rails reload the code after each request in development mode
+Rails.configuration.to_prepare do
+ # Force loading of all classes in the CTI hierachy by referencing the leaf classes here
+ Car
+ MotorCycle
+end
+```
+
+## Associations
+
+Associations (`has_many`, `has_one`, etc.) work and are inherited as you would expect. The only caveat is that
+in Rails 4 it might be necessary to explicitly specify the join table when using `has_and_belongs_to_many`.
+
## API
### Models
dbview_cti adds two class methods to ActiveRecord::Base:
@@ -209,11 +245,14 @@
The `change` syntax is not (yet?) supported for recreating database views.
## Notes
-* Using dbview_cti doesn't interfere with foreign key constraints. In fact, I recommend adding foreign key constraints
+* Using dbview_cti doesn't interfere with foreign key constraints. In fact, I highly recommend adding foreign key constraints
between the tables in a CTI hierarchy (e.g. using [foreigner](https://github.com/matthuhiggins/foreigner)).
+* When creating foreign key constraints involving tables that are part of the hierarchy, always refer to the tables
+themselves, not the views. When modifying the models in future migrations, the views may need to be recreated, which
+would cause problems with the foreign key constraints.
* Take care when using database id's. Since the data for a Car object is spread over several tables,
the id of a Car instance will generally be different than the id of the MotorVehicle instance you get when you
convert the Car instance to a MotorVehicle.
* The gem intercepts calls to destroy to make sure all rows in all tables are removed. This is not the case for
delete_all, however, so avoid using delete_all for classes in the CTI hierarchy.