2013-05-30 3 views
1

Я не эксперт в области баз данных и реляционной логики, и я немного смущен тем, что я должен делать в следующей ситуации.ruby ​​datamapper - симметричное самореферентное отношение «многие ко многим»

У меня есть модель Expression, где я хочу реализовать TranslationPair самостоятельно ссылаясь на многие отношения.

class Expression 
    include DataMapper::Resource 

    has n, :translation_pairs, child_key: [:exp_1_id] 
end 

class TranslationPair 
    include DataMapper::Resource 

    belongs_to :exp_1, 'Expression', key: true 
    belongs_to :exp_2, 'Expression', key: true 
end 

Проблема заключается в том, что я хотел бы translation_pairs отношений, чтобы вернуться не только TranslationPair экземпляров с данным выражением в exp_1 поле, но и TranslationPair экземпляров с данным выражением в exp_2 поле (если expression1 является переводом expression2, затем expression2 - это перевод expression1). Вид дизъюнкции в опции child_key. Что-то вроде:

has n, :translation_pairs, child_key: [:exp_1_id] or [:exp_2_id] 

Могу ли я реализовать его непосредственно в декларации модели или мне нужно реализовать какой-то пользовательский метод?

ответ

1

Интересная проблема!

Невозможно сделать это, как описано, только с помощью основных методов DataMapper. Я просто рассуждал о природе данных теперь ... но мне интересно, если вы могли бы быть в состоянии придумать с «каноническим» представлением любого данного Expression таким образом, что она может выглядеть следующим образом:

class Expression 
    belongs_to :canonical_translation 
    ... 

    def equivalent_expressions 
    canonical_translation.expressions.all(:id.not => self.id) 
    end 
end 

class CanonicalTranslation 
    property :representation, SomeDataType 
    has n :expressions 
end 

Если нет, вы можете использовать специальный метод для объекта Expression, например:

has n, :these_translations, :model => TranslationPair, :child_key => [:exp_1] 
has n, :those_translations, :model => TranslationPair, :child_key => [:exp_2] 

def translation_pairs 
    these_translations + those_translations 
end 
+0

Спасибо @mltsy. Оба варианта интересны. Первый философский (:)) хорош, но я не чувствую себя комфортно с изменением дизайна моей модели (даже если это будет не слишком сложно) только для своего рода ограничения DataMapper (я не уверен, но я думаю что то, что я хочу сделать, возможно в чистой схеме SQL). Я попробую со вторым, потому что в будущем это будет намного легче изменить. –

+0

Существует проблема с добавлением 'these_translations' и' these_translations'. Это 'DataMapper :: Associations :: OneToMany :: Collection', которые он не наследует от' Array', поэтому '+' не ведет себя как ожидаемая конкатенация (метод существует и делает некоторые причудливые вещи с объектом свойства, которые я не могу объяснить). Решение состоит в том, чтобы преобразовать их 'to_a'. Конечно, вы теряете возможности «Collection», но знаете, я могу жить без них ... –