Domanda

I'm not an expert in databases and relational logic and I'm a bit confused about what I have to do in the following situation.

I have a model Expression where I want to implement a TranslationPair self referencing many to many relationship.

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

The problem is that I would like translation_pairs relationship to return not only TranslationPair instances with a given expression in the exp_1 field, but also TranslationPair instances with the given expression in the exp_2 field (if expression1 is a translation of expression2, then expression2 is a translation of expression1). A kind of disjunction in the child_key option. Something like:

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

Can I implement it directly in the model declaration or I have to implement some custom method?

È stato utile?

Soluzione

Interesting problem!

There is no way to do this as described, just with DataMapper core methods. I'm just speculating about the nature of the data now... but I am curious if you might be able to come up with a "canonical" representation of any given Expression such that it could look like:

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

If not, you may be forced to use a custom method on the Expression object, something like:

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top