diff options
Diffstat (limited to 'guides/source/association_basics.md')
-rw-r--r-- | guides/source/association_basics.md | 76 |
1 files changed, 70 insertions, 6 deletions
diff --git a/guides/source/association_basics.md b/guides/source/association_basics.md index dab885a8fb..3484627a78 100644 --- a/guides/source/association_basics.md +++ b/guides/source/association_basics.md @@ -171,7 +171,7 @@ class CreateCustomers < ActiveRecord::Migration end create_table :orders do |t| - t.belongs_to :customer, index:true + t.belongs_to :customer, index: true t.datetime :order_date t.timestamps null: false end @@ -691,7 +691,7 @@ c.first_name = 'Manny' c.first_name == o.customer.first_name # => false ``` -This happens because c and o.customer are two different in-memory representations of the same data, and neither one is automatically refreshed from changes to the other. Active Record provides the `:inverse_of` option so that you can inform it of these relations: +This happens because `c` and `o.customer` are two different in-memory representations of the same data, and neither one is automatically refreshed from changes to the other. Active Record provides the `:inverse_of` option so that you can inform it of these relations: ```ruby class Customer < ActiveRecord::Base @@ -726,10 +726,10 @@ Most associations with standard names will be supported. However, associations that contain the following options will not have their inverses set automatically: -* :conditions -* :through -* :polymorphic -* :foreign_key +* `:conditions` +* `:through` +* `:polymorphic` +* `:foreign_key` Detailed Association Reference ------------------------------ @@ -2243,3 +2243,67 @@ Extensions can refer to the internals of the association proxy using these three * `proxy_association.owner` returns the object that the association is a part of. * `proxy_association.reflection` returns the reflection object that describes the association. * `proxy_association.target` returns the associated object for `belongs_to` or `has_one`, or the collection of associated objects for `has_many` or `has_and_belongs_to_many`. + +Single Table Inheritance +------------------------ + +Sometimes, you may want to share fields and behavior between different models. +Let's say we have Car, Motorcycle and Bicycle models. We will want to share +the `color` and `price` fields and some methods for all of them, but having some +specific behavior for each, and separated controllers too. + +Rails makes this quite easy. First, let's generate the base Vehicle model: + +```bash +$ rails generate model vehicle type:string color:string price:decimal{10.2} +``` + +Did you note we are adding a "type" field? Since all models will be saved in a +single database table, Rails will save in this column the name of the model that +is being saved. In our example, this can be "Car", "Motorcycle" or "Bicycle." +STI won't work without a "type" field in the table. + +Next, we will generate the three models that inherit from Vehicle. For this, +we can use the `--parent=PARENT` option, which will generate a model that +inherits from the specified parent and without equivalent migration (since the +table already exists). + +For example, to generate the Car model: + +```bash +$ rails generate model car --parent=Vehicle +``` + +The generated model will look like this: + +```ruby +class Car < Vehicle +end +``` + +This means that all behavior added to Vehicle is available for Car too, as +associations, public methods, etc. + +Creating a car will save it in the `vehicles` table with "Car" as the `type` field: + +```ruby +Car.create color: 'Red', price: 10000 +``` + +will generate the following SQL: + +```sql +INSERT INTO "vehicles" ("type", "color", "price") VALUES ("Car", "Red", 10000) +``` + +Querying car records will just search for vehicles that are cars: + +```ruby +Car.all +``` + +will run a query like: + +```sql +SELECT "vehicles".* FROM "vehicles" WHERE "vehicles"."type" IN ('Car') +``` |