This project is archived and is in readonly mode.

#3587 ✓stale
Gustav Broberg

Primary key value is not properly quoted with has_many :through using belongs_to

Reported by Gustav Broberg | December 16th, 2009 @ 09:07 PM

The has_many :through association where the through association is a belongs_to, (a feature introduced by #323) can generate SQL queries with an unquoted primary key value.

The following example will fail when the has_many :through association is used and Ocean's primary key value is something that needs quoting.

    class Fisherman < ActiveRecord::Base
      belongs_to :ocean
      has_many :crabs, :through => :ocean

    class Ocean < ActiveRecord::Base
      # Ocean's primary key is e.g. a string
      has_many :crabs
    class Crab < ActiveRecord::Base; end

Here is an example of what this might yield:

>> f = Fisherman.first
=> #<Fisherman id: 2, ocean_id: "atlantic">
>> f.crabs

ActiveRecord::StatementInvalid: [...]
 no such column: atlantic:
  SELECT "crabs".* FROM "crabs"
  INNER JOIN "oceans" ON "crabs".ocean_id = "oceans".id
  WHERE (("oceans".id = atlantic))

The bug is in HasManyThroughAssociation's construct_quoted_owner_attributes. It properly quotes the primary key value for the two other types of has_many :through, but not the belongs_to:

    # Associate attributes pointing to owner, quoted.
    def construct_quoted_owner_attributes(reflection)
      if as = reflection.options[:as]
        { "#{as}_id" => owner_quoted_id,
          "#{as}_type" => reflection.klass.quote_value(
            reflection.klass.columns_hash["#{as}_type"]) }
      elsif reflection.macro == :belongs_to
        { reflection.klass.primary_key => @owner[reflection.primary_key_name] }
        { reflection.primary_key_name => owner_quoted_id }

This is clearly wrong as the method name and comment indicates that it should quote the attributes. The code in question was commited in 95e1cf4812.... I have attached a simple patch to add the needed quoting.

Comments and changes to this ticket

Create your profile

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

<h2 style="font-size: 14px">Tickets have moved to Github</h2>

The new ticket tracker is available at <a href=""></a>