Association Join Models in Rails

As I re-learn Rails, I'm documenting concepts that seem different to me coming from a Cocoa/Core Data background. Association join models don't exist at the modeling level in Core Data.

The idea is essentially that you're taking a relationship that's two degress of separation and shortening it to just one. The Rails Wiki uses the example of three Entities:
Catalogue <-->> CatalogueItem <--> Product

Typically, to get all of the Product instances in a Catalogue, you'd do this:
catalogue.catalogue_items.collect{|item| item.product}

However, if you use the :through bit, you can access the products directly:
class Catalogue < ActiveRecord::Base
  has_many :catalogue_items
  has_many :products, :through => :catalogue_items
end


Meaning you can do this:
catalogue.products

In Core Data, I think you'd just do this with a custom accessor, or possibly a fetched property. Here's another example (also a Scott, but not me) of how this construct saves you from dropping down to SQL for some searches.
Design Element
Association Join Models in Rails
Posted Dec 29, 2006 — 3 comments below




 

Chris Hanson — Dec 30, 06 2955

Core Data doesn't have these because the typical use for such a join table is to implement a many-to-many relationship. Since Core Data natively supports to-one and to-many relationships, and also handles inverse management automatically, in the case of the SQLite persistent store it'll also transparently manage the join table for a to-many relationship with a to-many inverse.

If you actually need to model a relationship via a separate entity, on the other hand, you'll have to model that explicitly. To provide a way of accessing the objects on the other side of that relationship, you can use transient relationships with accessor methods that do the heavy lifting. However, these transient relationships can only be used with in-memory queries; queries that don't cause full managed objects to be created won't be able to use them.

James Randall — Dec 30, 06 2956

Much as I like Rails the way you end up littering your code with these declarations is one of the things I dislike. I think collecting this information in a single place would make for a clearer model.

Scott Stevenson — Dec 30, 06 2957 Scotty the Leopard

the typical use for such a join table is to implement a many-to-many relationship. Since Core Data natively supports to-one and to-many relationships, and also handles inverse management automatically

I'm still new at Rails concepts, but I'm not sure this really covers the whole picture. Rails natively supports many-to-many inverse relationships. In the O'Reilly book they use the example of photos and categories:

has_and_belongs_to_many :photos has_and_belongs_to_many :categories

Which allows you you do things like this:

category.photos << new_photo photo.categories << new_category

The join table is handled transparently, just as in Core Data (other than the fact that you have to create the migration).

In the same book, the association join models come into play when the Slideshow, Slide, and Photo classes are used together. A Slide has a belongs_to relationship to both Slideshow and Photo.

A Slide is more than just a simple join because it maintains information about a Photo which is specific to a Slideshow. In other words, the Slide could maintain a caption but have its Photo reference change. An association from Slideshow to Photo using :through is just a convenience.

The example on this page gives a better example. Let me know if you still think the original point is valid. I'd be curious to know if I'm missing something about Rails here.




 

Comments Temporarily Disabled

I had to temporarily disable comments due to spam. I'll re-enable them soon.





Copyright © Scott Stevenson 2004-2015