Association through many models

  • Feb 17

You can chain several models through assocations, not limited by many-to-many relationship. For example, you might have models like this:

class User < ActiveRecord::Base
  has_many :ownerships
  has_many :articles, through: :ownerships
end

class Article < ActiveRecord::Base
  has_many :taggings
  has_many :tags, through: :taggings
end

There are five models: User, Ownership, Article, Tagging, Tag. To get the tags belongs to one user, you can do this:

Tag.joins(taggings: {articles: {ownerships: :user}}).uniq.where('users.id = ?', User.first)

You can put this long join into the scopes.

To use assocation, try this:

class User < ActiveRecord::Base
  has_many :ownerships
  has_many :articles, through: :ownerships
  has_many :taggings, through: :articles, source: :taggings
  has_many :tags, through: :taggings, source: :tags
end

Then you can get tags via:

User.first.tags

To avoid duplication, you might need to add .uniq to the query.