#1164 new
Giao Phan

ManyToOne Relationships form bad sql with links

Reported by Giao Phan | December 21st, 2009 @ 07:01 PM

When adding a link from the 'belongs_to' side, the sql generated is incorrect. It joins the model with itself, instead of with the other model. It looks like relationship.source_model is the model, so in join_statement you get the incorrect self join.

Comments and changes to this ticket

  • Giao Phan

    Giao Phan December 21st, 2009 @ 07:02 PM

    • no changes were found...
  • Giao Phan

    Giao Phan January 4th, 2010 @ 02:59 PM

    It looks like links was deprecated at some point. What's the proper way now to pull associated tables in so that you can do things like sorting on that assocation:

  • Giao Phan

    Giao Phan January 4th, 2010 @ 05:41 PM

    Ended up working around this by getting the relationship object, and calling inverse on it, and passing that as the link.

  • Richard Livsey

    Richard Livsey January 16th, 2010 @ 04:02 PM

    Just ran into this issue myself too when upgrading to 0.10.2

  • DAddYE

    DAddYE January 18th, 2010 @ 04:29 AM

    Giao Phan,

    can you put your code for resolve this problem?

  • DAddYE

    DAddYE January 18th, 2010 @ 06:40 AM


    Album.all(:links => [Album.relationships[:artist].inverse])

    Woww work but it's normal that is so complex?

    Then for ordering (also super iper mega complex)

    Album.all(:order => [DataMapper::Query::Direction.new(Artist.properties[:name])], 
              :links => [Album.relationships[:artist].inverse])

    Didn't work... say me that

    ArgumentError - +options[:order]+ entry :name does not map to a property in Album
  • DAddYE

    DAddYE January 18th, 2010 @ 08:23 AM

    Mmm, found!

    There is a bug here http://github.com/datamapper/dm-core/blob/master/lib/dm-core/query....


    when Operator, Direction
                operator = order_entry.operator
                unless operator == :asc || operator == :desc
                  raise ArgumentError, "+options[:order]+ entry #{inspect} used an invalid operator #{operator}"
                assert_valid_order([ order_entry.target ], fields)

    Cycle validations only on the current model, but we need to change to order_entry.target!

  • Johan Kellum

    Johan Kellum March 2nd, 2010 @ 11:29 AM

    • Tag set to relationships links inverse query

    This monkey patch will allow you to use the less verbose string/symbol with the :links option.
    It simply adds the inverse. It works for 1-many, many-1 and many-many.
    It's especially useful for a has_many :through
    Ex. User.all(:links => [:roles])

    module DataMapper
      class Query
        def normalize_links
          stack = @links.dup
          while link = stack.pop
            relationship = case link
              when Symbol, String             then @relationships[link].inverse
              when Associations::Relationship then link
            if relationship.respond_to?(:links)
            elsif !@links.include?(relationship)
              repository_name = relationship.relative_target_repository_name
              model           = relationship.target_model
              # TODO: see if this can handle extracting the :order option and sort the
              # resulting collection using the order specified by through relationships
              model.current_scope.merge(relationship.query).each do |subject, value|
                # TODO: figure out how to merge Query options from links
                if OPTIONS.include?(subject)
                  next  # skip for now
                # set @repository when appending conditions
                original, @repository = @repository, DataMapper.repository(repository_name)
                  append_condition(subject, value, model)
                  @repository = original
              @links << relationship

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »