Шаблон для однонаправленного соединения has_many? - PullRequest
1 голос
/ 02 июня 2009

Мне пришло в голову, что если у меня есть соединение has_many, в котором внешняя модель не имеет own_to, и поэтому соединение является односторонним, тогда мне фактически не нужен внешний ключ.

У нас может быть столбец category_ids, в котором хранится маршализованный массив идентификаторов, который мы можем передать find.

Итак, вот непроверенный пример:

class page < AR

  def categories
    Category.find(self.category_ids)
  end

  def categories<<(category)
    # get id and append to category_ids
    save!
  end

  def category_ids
    @cat_ids ||= Marshal.load(read_attribute(:category_ids)) rescue []
  end

  def category_ids=(ids)
    @cat_ids = ids
    write_attribute(:category_ids, ids)
  end

end

page.category_ids => [1,4,12,3] page.categories => Массив категории

Есть ли уже принятый шаблон для этого? Это часто или просто не стоит усилий?

Ответы [ 2 ]

1 голос
/ 25 ноября 2009

Я согласен с Омаром, что это, похоже, не стоит усилий.

Ваша база данных больше не отражает вашу модель данных и не собирается оказывать какую-либо помощь в обеспечении этих отношений. Кроме того, теперь вы должны поддерживать синхронизацию массива маршализованных идентификаторов с таблицей категорий и обеспечивать уникальность для всех страниц, если хотите ограничить отношение has_many.

Но я думаю, что наиболее важно, в чем выгода этого подхода? Это увеличит сложность и увеличит объем кода, который вы должны написать.

1 голос
/ 03 июня 2009

Не скажется ли здесь производительность, когда вы выполняете маршалинг / демаршаллинг?

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

На самом деле это выглядит как сопоставление «многие ко многим», а не «многие к одному», так как нет кода, который запрещает принадлежность категории к более чем одной странице, конечно, вы хотите что-то вроде:

create table categories_pages (
  category_id integer not null references categories(id),
  page_id integer not null references pages(id),
  primary_key(category_id, page_id)
);

со значением has и принадлежит многим с обеих сторон или has_many: сквозным с обеих сторон (в зависимости от того, хотите ли вы хранить больше вещей).

...