Ассоциация моделей Rails для каталога подкастов (Polymoprhic или HABTM)

Я создаю приложение, которое будет каталогом для подкастов/радиопередач (в основном, для заметок каждого шоу). Я застрял в том, как смоделировать людей в этом приложении, главным образом потому, что человек может быть одновременно гостем во многих разных эпизодах (в рамках многих разных шоу), но также может быть ведущим (тем, кто фигурирует в каждом эпизоде ​​данного шоу).

Пример: Марко Армент является ведущим шоу «Build and Analyze», но может время от времени появляться в качестве гостя в других подкастах (таких как «The Gruber Talk Show» или «This Week in Tech»).

Моя модель данных на данный момент показана ниже (с упором на отношения ведущий/гостевой эпизод/шоу). Я не уверен, как подойти к моделированию человека/гостя/хозяина, хотя я уверен, что хочу сохранить роли «Гость» и «Хост» как отдельные элементы в приложении.

Episode
  title:string
  has_many :guests

Show
  title:string
  has_many :hosts

Host
  show_id:integer
  person_id:integer
  belongs_to :show

Guest
  episode_id:integer
  person_id:integer
  belongs_to :episode

People
  name:string
  # ???

Должен ли я просто избавиться от моделей «хозяин» и «гость» и вместо этого определять эти броски на основе того, запрашивают ли Эпизоды или Шоу людей, связанных с ними? Помните, что у «Шоу» могут быть только ведущие, а у «Эпизода» могут быть только гости, но гости и ведущие всегда являются Людьми (имя, биография, никнейм в Твиттере и т. д.).

Спасибо. Я изучил полиморфную ассоциацию и has_many :through и не уверен, что использовать, если да.

ОБНОВЛЕНИЕ №1

После того, как я выспался, у меня появилось несколько лучших идей о том, как справиться с этим утром. Подобно ответу @Emm ниже, кажется естественным, что «Хозяин» и «Гость» должны быть просто некоторым качеством Человека через отдельную модель. Вот мое новое мнение о структуре модели, которое я настроил до того, как увидел какой-либо из ответов ниже.

Ключевое отличие здесь заключается в том, что модель «Внешний вид» будет иметь столбец «роль» (строка), где я могу указать, является ли person_id, связанный с этой строкой, «гостем» или «хозяином» для Episode_id или show_id этой строки.

class Appearanceship
  # person_id:integer
  # episode_id:integer
  # show_id:integer
  # role:string
  belongs_to :people
  belongs_to :episodes
  belongs_to :shows
end

class Person
  # name, bio, profile pic, twitter name, etc
  has_many :appearanceships
  has_many :episodes, :through => :appearanceships
  has_many :shows, :through => :appearanceships
end

class Episode
  # title, summary, date recorded, mp3 URL, web URL, etc
  has_many :appearanceships
  has_many :people, :through => :appearanceships
end

class Show
  # title, description, web URL, RSS URL, etc
  has_many :appearanceships
  has_many :people, :through => :appearanceships
end

class Network
  # e.g., "NPR", "5by5", "Mule Radio Syndicate", "Revision3"
  # title, description, web URL, etc
  has_many :shows
end



Ответы (3)


Вы говорите только о двух разных моделях, так что я бы сказал проще. Давайте объединим People, Host и Guest в Person; и давайте объединим Episode и Show в Podcast. Вы можете определить различия ролей между хостом и гостем в другом месте.

class Person < ActiveRecord::Base
  attr_accessible :name, :biography, :twitter
  has_many :podcasts
  has_many :podcasts, :through => :roles
end

class Podcast < ActiveRecord::Base
  attr_accessible :title
  has_many :persons
  has_many :persons, :through => :roles
end

class Role < ActiveRecord::Base
  attr_accessible :variety
  belongs_to :podcast
  belongs_to :person
end

И сохраните в variety в Role тип отношения между Person и Podcast. Это может быть строка вроде "host" или "guest", или вы даже можете создать другую модель с именем Variety для управления ею (и, таким образом, сохранить variety_id вместо variety в Role).

person okay56k    schedule 22.03.2013

шоу имеет много пользователей через хосты

в сериале много серий

эпизод имеет много пользователей через гостей

class User < ActiveRecord::Base
  has_many :shows, :through => :show_hosts
  has_many :show_hosts

  has_many :episodes, :through => :show_guests
  has_many :show_guests
end
person Hass    schedule 22.03.2013

Лучшим выбором будет не разделять Хост и Гость, Гость может быть определен как самореференциальные отношения с использованием HABTM.

определение вашей модели будет выглядеть примерно так,

class Host < ActiveRecord::Base
  has_and_belongs_to_many :guest, 
      :join_table => 'guests' #This is HABTM join table that you will have to create
      :foreign_key => 'host_id'
      :association_foreign_key => 'guest_id'
      :class_name => 'Host'


#The migration will look like this,
def change
  create_table :guests :id => false do |t|
    t.integer :host_id,  :null => false
    t.integer :guest_id, :null => false
  end
  add_index :guests, [:host_id, :guest_id]
end
person Monis    schedule 22.03.2013