Robot Has No Heart

Xavier Shay blogs here

A robot that does not have a heart

Updating Class Table Inheritance Tables

My last post covered querying class table inheritance tables; this one presents a method for updating them. Having set up our ActiveRecord models using composition, we can use a standard rails method accepts_nested_attributes_for to allow easy one-form updating of the relationship.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Item < ActiveRecord::Base
  validates_numericality_of :quantity

  SUBCLASSES = [:dvd, :car]
  SUBCLASSES.each do |class_name|
    has_one class_name
  end

  accepts_nested_attributes_for *SUBCLASSES
end

@item = Dvd.create!(
  :title => 'The Matix',
  :item  => Item.create!(:quantity => 1))

@item.update_attributes(
  :quantity => 2,
  :dvd_attributes => {
    :id    => @item.dvd.id,
    :title => 'The Matrix'})

This issues the following SQL to the database:

1
2
UPDATE "items" SET "quantity" = 10 WHERE ("items"."id" = 12)
UPDATE "dvds" SET "title" = 'The Matrix' WHERE ("dvds"."id" = 12)

Note that depending on your application, you may need some extra locking to ensure this method is concurrent, for example if you allow items to change type. Be sure to read the accepts_nested_attributes_for documentation for the full API.

I talk about this sort of thing in my “Your Database Is Your Friend” training sessions. They are happening throughout the US and UK in the coming months. One is likely coming to a city near you. Head on over to www.dbisyourfriend.com for more information and free screencasts

  1. erwan says:

    Hi Xavier,

    I'm working on a real estate site and choosed STI for homes, flats, plots... plus they have different behaviours with prices (buying, letting per month/week, holidays renting).
    I must admit that it is not as clean as I'd like because there are a lot of empty fields like garden for a flat or bedrooms for a plot, what do you think about it? Do you think CTI is the right choice?

  2. Xavier Shay says:

    It is hard to say without being more familiar with your domain. I would recommend a spike to see what CTI would look like for you and then you can decide whether it will provide benefits.

Post a comment


(lesstile enabled - surround code blocks with ---)

A pretty flower Another pretty flower