Сравнение has_many :through и has_and_belongs_to_many

Posted on February 06, 2007
Для связи 2х моделей в Rails через таблицу связей имеется 2 типа связи habtm и has_many :through
Рассмотрим стандартный пример из Wiki:

1. has_and_belongs_to_many - Связь таблицей


#таблица связи
create_table "dancers_movies", :id => false do |t|
  t.column "dancer_id", :integer, :null => false
  t.column "movie_id",  :integer, :null => false
end
#и модели
class Dancer < ActiveRecord::Base
  has_and_belongs_to_many :movies
end

class Movie < ActiveRecord::Base
  has_and_belongs_to_many :dancers
end
Очень просто в использовании, таблица соединений имеет всего 1 ключ и 2 поля, больше полей использовать нельзя.

has_many :through - связь через модель


#таблица
create_table "appearances", do |t|
  t.column "dancer_id",      :integer, :null => false
  t.column "movie_id",       :integer, :null => false
  t.column "character_name", :string
  t.column "dance_numbers",  :integer
end
#модель
class Appearance < ActiveRecord::Base
  belongs_to :dancer
  belongs_to :movie
end

class Dancer < ActiveRecord::Base
  has_many :appearances, :dependent => true
  has_many :movies, :through => :appearances
end

class Movie < ActiveRecord::Base
  has_many :appearances, :dependent => true
  has_many :dancers, :through => :appearances
end
Связывающая модель является обычным объектом со всеми его плюсами и минусами (не следует забывать о потреблении памяти ;))

подведение результатов

итак, вот сравнение преимуществ и недостатков этих двух способов
habtm
Чтоhas_many :through
Primary Key-+
дополнительные параметры ассоциации-+
Полиморфизм-+

При составлении использовалась хорошая статья http://blog.hasmanythrough.com/2006/04/20/many-to-many-dance-off