Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Reflection do not reset quoted_table name when set_table_name is invoked

#4568

Hi all,

I just found this issue :

class User < ActiveRecord::Base
has_many :stats
end
class Stat < ActiveRecord::Base
  belongs_to :user
end

Somewhere in my code I have to set the table name of my Class Stat with it's id (multiple stats tables depending on user's id)

user1 = User.find 1
user2 = User.find 2

Stat.set_table_name "stats_#{user1.id}"
Stat.table_name #=> 'stats_1'
Stat.quoted_table_name #=> '`stats_1`'

user1.stats.find(:conditions => {:generated_at => Date.today})

It works fine : I can see in the log :

Stat Load (0.3ms)   SELECT * FROM `stats_1` WHERE (`stats_1`.`generated_at` = '2010-05-10') AND (`stats_1`.user_id = 1)

But when I change to stats_2 :

Stat.set_table_name "stats_#{user2.id}"
Stat.table_name #=> 'stats_2'
Stat.quoted_table_name #=> '`stats_2`'

user2.stats.find(:conditions => {:generated_at => Date.today})
Stat Load (0.0ms)   Mysql::Error: Unknown column 'stats_1.generated_at' in 'where clause': SELECT * FROM `stats_2` WHERE (`stats_1`.`generated_at` = '2010-05-10') AND (`stats_1`.user_id = 2)

After digging into active_record I think I've found it. Reflection sets an instance variable for table_name and quoted_table_name

So I added this to my initializers and all worked fine !! (Just remove the instance_variable set)

module ActiveRecord
  module Reflection
    class AssociationReflection < MacroReflection 
      def table_name
        klass.table_name
      end
      def quoted_table_name
        klass.quoted_table_name
      end
    end
  end
end

Reported by Hery · May 10th, 2010 @ 01:49 PM

State: resolved
Milestone: 3.0.2
Assigned to: Pratik Pratik
Importance: Low

Activity

  1. Neeraj Singh
    Neeraj Singh
        def quoted_table_name
            @quoted_table_name ||= connection.quote_table_name(table_name)
        end
    

    Above code can easily be modified to not to do memoization given that to get the quoted_name no database call is made. However quoted_table_name is called so many times that it is better to have faster access through an instance variable.

    I will let people with more domain knowledge in this field decide if this should be fixed.

    May 10th, 2010 @ 10:13 PM

  2. Ryan Bigg
    Ryan Bigg
    • Tag set to bugmash
    • State changed from new to incomplete

    Please submit a patch (with tests) for this issue.

    May 13th, 2010 @ 11:44 PM

  3. Santiago Pastorino
    Santiago Pastorino
    • Milestone cleared.
    • Tag changed from bugmash to activerecord, bugmash
    • State changed from incomplete to open

    Please we have to be nice don't close the ticket we have some information.
    I'm digging on this.

    May 14th, 2010 @ 11:40 PM

  4. Santiago Pastorino
    Santiago Pastorino
    • State changed from open to verified

    Patch for master

    May 14th, 2010 @ 11:54 PM

  5. Santiago Pastorino
    Santiago Pastorino
    • Assigned user set to Pratik

    A better one

    May 15th, 2010 @ 12:19 AM

  6. Repository
  7. Jeremy Kemper
    Jeremy Kemper
    • Milestone set to 3.0.2
    • Importance changed from to Low

    October 15th, 2010 @ 11:01 PM