Схема именования пользовательских типов ActiveRecord - PullRequest
7 голосов
/ 29 июля 2011

Я имею дело с таблицей, в которой уже есть столбец с именами естественных типов. Например. уже существует столбец с именем «provider», который имеет значения «foo» или «bar». Я хочу использовать STI для этой таблицы, используя существующие имена типов, так как кажется глупым добавлять дополнительный столбец с именем 'type' для использования Active Record. Проблема в том, что эти имена типов не совпадают точно с классами ruby. Я надеялся, что смогу настроить собственное отображение, например Class1 => foo, Class2 => bar.

Я попробовал следующее:

# In the base class
set_inheritance_column :provider

# In Class1
def self.sti_name
    'foo'
end

# In Class2
def self.sti_name
    'bar'
end

Но это не похоже на это, я получаю:

The single-table inheritance mechanism failed to locate the subclass: 'foo'
...
activerecord (3.0.8) lib/active_record/base.rb:923:in `find_sti_class'

Похоже, ActiveRecord оборудован только для обработки полных имен классов и демодуляризованных имен классов. Я не совсем уверен, для чего вообще нужен защищенный метод sti_name.

Я собираюсь углубиться в структуру и переопределить ActiveRecord :: Base.compute_type. Прежде чем я это сделаю, кто-нибудь делал это раньше? Это погоня за диким гусем?

Могут ли rails обрабатывать имена пользовательских типов, или я застрял с именами классов Ruby?

Обновление

Я получил это для работы:

# In the base class
def self.find_sti_class(type_name)
    # Do mapping from foo/bar to Class1/Class2
    ...
end

Я все еще опасаюсь решить еще несколько вопросов в будущем. Это правильный способ сделать это?

Ответы [ 2 ]

2 голосов
/ 11 января 2013

У меня была похожая ситуация, и я нашел решение по этой ссылке: https://gist.github.com/1381880

1 голос
/ 29 июля 2011

Глядя на код AR и просто сосредотачиваясь на sti_name и instantiate ... кажется, вам может быть достаточно обезьяньей заплатки за эти два метода.

У меня нет опыта с этим, но это не выглядит невероятно сложным.Вот как выглядит instantiate:

def instantiate(record)
  model = find_sti_class(record[inheritance_column]).allocate
  model.init_with('attributes' => record)
  model
end

В идеале вы хотите отсканировать код на предмет чего-либо, что ссылается на что-то вроде record[inheritance_column] или просто на inheritance_column, и вставить туда свой собственный код отображения.Просто быстрый взгляд, и кажется, что он не используется во многих местах.

Я бы сказал, что вы пытаетесь, это возможно :), но вам понадобятся тестовые примеры для базовых реализаций + вещи, в которых участвуют ассоциации, чтобы AR мог найти и построить правильный SQL для различных случаев..

Понятно, что AR не был создан с учетом того, что вы пытаетесь, поскольку использование inheritance_column в коде явно нигде не абстрагировано.Вот почему вам нужно побольше поковыряться в коде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...