1

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?

Waiting for Dev...
  • 12,629
  • 5
  • 47
  • 57

1 Answers1

1

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
mltsy
  • 6,598
  • 3
  • 38
  • 51
  • Thanks @mltsy. Both alternatives are interesting. The first philosophical one (:)) is nice, but I don't feel comfortable with changing my model design (even if it would not be too difficult) just for a kind of DataMapper limitation (I'm not sure, but I think that what I want to do is possible in a pure SQL schema). I'll try with the second one, because It will be a lot easier to change in the future. – Waiting for Dev... Jun 28 '13 at 07:12
  • There is a problem with the addition of `these_translations` and `those_translations`. They are `DataMapper::Associations::OneToMany::Collection`, which it is not inheriting from `Array`, so the `+` is not behaving as the expected concatenation (the method exists and it makes some bizarre things with the object properties involved I can't explain). The solution is to transform them `to_a`. Of course you loose the `Collection` capabilities, but right know I can live without them... – Waiting for Dev... Oct 18 '13 at 11:48