Вопрос о правильных ассоциациях в Rails

Возьмем, к примеру, эту ситуацию.

У вас есть 3 модели:

  1. Поэт - представляет автора стихотворения.
  2. Поэма - Представляет собой стихотворение, написанное поэтом.
  3. Printing — представляет собой печатное издание любого рода, содержащее стихотворение поэта.

С самого начала поэт и стихотворение очевидны:

  • Поэт has_many стихи
  • Стихотворение belongs_to поэта

Меня смущает работа с моделью Printing.

В этом случае Печать в некотором смысле принадлежит и поэту, и стихотворению. Вы могли бы сказать, что у поэта есть_много изданий или у стихотворения есть_много изданий, что имеет смысл, но идти обратным путем сложно...

Как насчет ситуации, когда в каком-то журнале или книге напечатано 5 стихотворений одного поэта? ИЛИ одно из стихотворений опубликовано в 10 разных журналах?

Создается впечатление, что сама Печать «принадлежит многим» стихам или поэтам. Я знаю, что это неправильно, но я просто пытаюсь сформулировать мысль.

Итак, ответ на вопрос таков: как бы вы установили эти отношения? В частности, как будут выглядеть модель и таблица базы данных И как вы будете использовать их для доступа к связанным данным?

Спасибо!


person Mario Zigliotto    schedule 07.08.2011    source источник


Ответы (1)


Как насчет ситуации, когда в каком-то журнале или книге напечатано 5 стихотворений одного поэта?

Помните, что если у вас есть поэт, у которого много стихов, и печать, в которой тоже много стихов, вы всегда можете найти поэта.

Poet.poems.first.printings вернет все издания первого стихотворения поэта.

или вы можете сделать Printing.poems.first.poet Таким образом, вы можете получить поэта первого стихотворения в печати.

Как бы вы построили эти отношения? В частности, как будут выглядеть модель и таблица базы данных И как вы будете использовать их для доступа к связанным данным?

я бы поставил так

Poet :has_many poems
poem :belongs_to poet
poem :has_and_belongs_to_many printings
printing :has_many poems

Поскольку вы используете ассоциацию has_and_belogs_to_many, вам нужна таблица соединений для стихов и печатных изданий.

у вас будет миграция, которая выглядит так

CreatePoemsPrintingJoinTable < ActiveRecord::Migration
  def self.up
    create_table :poems_printings, :id => false do |t|
      t.integer :poem_id
      t.integer :printing_id
    end
  end

  def self.down
    drop_table :poems_printings
  end
end

Остальные таблицы довольно просты.

CreateTablePoems < ActiveRecord::Migration
  def self.up
    create_table :poems, do |t|
    t.integer :poet_id
    end
  end

  def self.down
    drop_table :poems
  end
end

CreateTablePoets < ActiveRecord::Migration
  def self.up
    create_table :poets do |t|
    end
  end

  def self.down
    drop_table :poems
  end
end

CreateTablePrintings < ActiveRecord::Migration
  def self.up
    create_table :printings do |t|
    end
  end

  def self.down
    drop_table :printings
  end
end
person austinbv    schedule 07.08.2011
comment
было бы сложнее, если бы стихотворение могло появиться во многих изданиях, не уверен, что это так? - person house9; 07.08.2011
comment
Это именно тот случай, и я только что обновил текст, когда вы, ребята, разместили ответы: X - person Mario Zigliotto; 07.08.2011
comment
Я бы предложил стихотворение has_and_belongs_to_many :printings в таком случае - person Peter Brown; 07.08.2011
comment
Я согласен, я всегда забываю habtm, я обновил свой ответ, чтобы отразить это - person austinbv; 07.08.2011
comment
Не могли бы вы добавить, как должны выглядеть таблицы БД для вашего решения? Я предполагаю, что это довольно просто, но просто хочу убедиться. - person Mario Zigliotto; 07.08.2011
comment
согласен - ознакомьтесь с руководствами по рельсам - guides.rubyonrails.org/ - person house9; 07.08.2011
comment
Я добавил миграции, но на самом деле просто собрал их вместе, так что не копируйте и не вставляйте их. Также в rails не создавайте явно таблицы, всегда используйте миграции. Это позволяет вам совершать ошибки - person austinbv; 07.08.2011
comment
ОстинБВ большое спасибо. Я попробую несколько вещей и в конечном итоге выберу ваш ответ, но сначала мне было интересно - почему бы вам не пойти с ассоциацией has_many :through? Не будет ли это более гибкой альтернативой? - person Mario Zigliotto; 07.08.2011
comment
снова вы должны прочитать руководства по рельсам, указанные выше, отношения, которые вы пытаетесь построить, насколько я понимаю, не являются сквозными, оба пути являются приемлемыми. есть гораздо лучшее описание, чем я могу дать вам на направляющие рельсы здесь. Также помните, если вам нравится мой ответ, примите это! Рад, что смог помочь - person austinbv; 07.08.2011
comment
На самом деле я читал руководство, но я не видел раздела 2.8, где они сравниваются, еще раз спасибо. - person Mario Zigliotto; 07.08.2011