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.

named_scope not preserving self

#1519

I have 2 named_scope in my topic model:


class Topic < ActiveRecord::Base
  belongs_to :forum, :counter_cache => true
  belongs_to :user

  named_scope :tracked, lambda { |u| { :include => [ :trackings, :last_post ], :conditions => [ "topics_tracking.user_id = ?", u ] }}
  named_scope :untracked, lambda { |t| { :conditions => [ "id NOT IN (?)", t ] }}

  def self.unread(user)
    marked = self.tracked(user)
    unread = self.untracked(marked)
    marked.each do |t|
      unread << t if t.trackings.first.mark.to_s(:db) < t.last_post.updated_at.to_s(:db)
    end
    unread
  end

If I call my forum model which has_many topics:


> forum = Forum.find(1)
> forum.topics.unread(user)
LOG:  durée : 4.776 ms, instruction : SELECT "topics"."id" AS t0_r0, "topics"."title" AS t0_r1, "topics"."forum_id" AS t0_r2, "topics"."posts_count" AS t0_r3, "topics"."user_id" AS t0_r4, "topics"."created_at" AS t0_r5, "topics"."updated_at" AS t0_r6, "topics"."sticky" AS t0_r7, "topics"."locked" AS t0_r8, "topics"."hits" AS t0_r9, "topics"."last_post_id" AS t0_r10, "topics"."fulltext" AS t0_r11, "topics_tracking"."id" AS t1_r0, "topics_tracking"."user_id" AS t1_r1, "topics_tracking"."topic_id" AS t1_r2, "topics_tracking"."mark" AS t1_r3, "topics_tracking"."created_at" AS t1_r4, "topics_tracking"."updated_at" AS t1_r5, "posts"."id" AS t2_r0, "posts"."body" AS t2_r1, "posts"."topic_id" AS t2_r2, "posts"."user_id" AS t2_r3, "posts"."created_at" AS t2_r4, "posts"."updated_at" AS t2_r5, "posts"."position" AS t2_r6, "posts"."fulltext" AS t2_r7 FROM "topics"  LEFT OUTER JOIN "topics_tracking" ON topics_tracking.topic_id = topics.id  LEFT OUTER JOIN "posts" ON "posts".id = "topics".last_post_id WHERE (("topics".forum_id = 1) AND (topics_tracking.user_id = 2))
LOG:  durée : 0.815 ms, instruction : SELECT * FROM "topics" WHERE (id NOT IN (5,10))

You can see that the first query fired by marked = self.tracked(user) uses WHERE (("topics".forum_id = 1) but not the second query !

the second named_scope lost the forum_id and requests all the topics although the two methods use self

Reported by EppO · December 5th, 2008 @ 05:55 PM

State: invalid
Milestone: 2.x
Assigned to: Frederick Cheung Frederick Cheung
Importance: none

Activity

  1. Frederick Cheung
    Frederick Cheung

    Is there anything more that might be relevant?

    I replicated a small example:

    
    class Child < ActiveRecord::Base
      belongs_to :parent
      named_scope :active, lambda {{:conditions => {:status => 'active'}, :include => :parent}}
      named_scope :other, lambda {|t| {:conditions => ["id not in (?)", t]}}
    
      def self.things
        foos = self.active
        self.other(foos).to_a
      end
    end
    

    with a Parent class that just has_many :children and this seem to work fine. Is there somethere elsewhere (in either of the two classes) that might be interfering? Can you construct a minimal example ?

    December 8th, 2008 @ 09:26 PM

  2. EppO
    EppO

    I tried your example with a fresh rails project and an error occurs (tested on OS X and debian linux):

    >> Child.all => [#, #, #]

    Child.things SystemStackError: stack level too deep

    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1974:in `with_scope'
    from (__DELEGATION__):2:in `__send__'
    from (__DELEGATION__):2:in `with_scope'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/named_scope.rb:169:in `method_missing'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/named_scope.rb:177:in `load_found'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/named_scope.rb:161:in `proxy_found'
    from (__DELEGATION__):2:in `is_a?'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:2183:in `sanitize_sql_array'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:2079:in `sanitize_sql'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1441:in `merge_conditions'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1439:in `each'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1439:in `merge_conditions'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1981:in `with_scope'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1978:in `each'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1978:in `with_scope'
    from (irb):2:in `inject'
    
    

    ... 2965 levels...

    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1439:in `merge_conditions'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1742:in `add_conditions!'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1629:in `construct_finder_sql'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1490:in `find_every'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:589:in `find'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/named_scope.rb:171:in `send'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/named_scope.rb:171:in `method_missing'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:2003:in `with_scope'
    from (__DELEGATION__):2:in `__send__'
    from (__DELEGATION__):2:in `with_scope'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/named_scope.rb:169:in `method_missing'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/named_scope.rb:177:in `load_found'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/named_scope.rb:161:in `proxy_found'
    from (__DELEGATION__):2:in `to_a'
    from /home/eppo/lighthouse/app/models/child.rb:8:in `things'
    from (irb):2>>
    
    

    I use sqlite 3 for this example, postgres driver for my first report

    December 8th, 2008 @ 11:26 PM

  3. EppO
    EppO

    Previous error occured when I call Child.things

    If I run Child.active and Child.other by hand in irb, that works. don't know why, but seems that error is related to my first report

    December 8th, 2008 @ 11:32 PM

  4. Frederick Cheung
    Frederick Cheung

    That scope was never supposed to work in that case :-). It was purely for doing some_parent.children.things, which (for me at least) did the queries I'd expect

    December 8th, 2008 @ 11:36 PM

  5. EppO
    EppO

    There is something wrong somewhere...

    @@ Loading development environment (Rails 2.2.2)

    forum = Forum.first => #Topic.untracked(forum.topics) SystemStackError: stack level too deep

        from /usr/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/core_ext/array/extract_options.rb:15:in `extract_options!'
        from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:582:in `find'
        from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/associations/association_collection.rb:60:in `find'
        from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/associations/association_collection.rb:390:in `find_target'
        from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/associations/association_collection.rb:344:in `load_target'
        from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/associations/association_proxy.rb:208:in `method_missing'
        from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/associations/association_collection.rb:361:in `method_missing'
        from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:2183:in `sanitize_sql_array'
        from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:2079:in `sanitize_sql'
        from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1441:in `merge_conditions'
        from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1439:in `each'
        from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1439:in `merge_conditions'
        from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1742:in `add_conditions!'
        from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1629:in `construct_finder_sql'
        from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1490:in `find_every'
        from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:589:in `find'
    
    

    ... 2690 levels...

        from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:2003:in `with_scope'
        from (__DELEGATION__):2:in `__send__'
        from (__DELEGATION__):2:in `with_scope'
        from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/named_scope.rb:169:in `method_missing'
        from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/named_scope.rb:177:in `load_found'
        from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/named_scope.rb:161:in `proxy_found'
        from (__DELEGATION__):2:in `inspect'
        from /usr/lib/ruby/1.8/irb.rb:302:in `output_value'
        from /usr/lib/ruby/1.8/irb.rb:151:in `eval_input'
        from /usr/lib/ruby/1.8/irb.rb:263:in `signal_status'
        from /usr/lib/ruby/1.8/irb.rb:147:in `eval_input'
        from /usr/lib/ruby/1.8/irb.rb:146:in `eval_input'
        from /usr/lib/ruby/1.8/irb.rb:70:in `start'
        from /usr/lib/ruby/1.8/irb.rb:69:in `catch'
        from /usr/lib/ruby/1.8/irb.rb:69:in `start'
        from /usr/bin/irb:13>> 
    
    

    bla = forum.topics => [#, #] Topic.untracked(bla) => [] Topic.untracked(forum.topics) => []

    @@

    Twice the same method call, 2 different results, same code. Find my simple code in attachment. Just unzip and test same calls in console.

    December 11th, 2008 @ 02:42 PM

  6. EppO
    EppO

    formatting mistake (what a pity no preview available), I put again my script/console test:

    
    Loading development environment (Rails 2.2.2)
    >> forum = Forum.first
    => #<Forum id: 1, name: "bla bla", desc: "blabla forum de tesst", created_at: "2008-12-11 14:28:18", updated_at: "2008-12-11 14:28:18">
    >> Topic.untracked(forum.topics)
    SystemStackError: stack level too deep
            from /usr/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/core_ext/array/extract_options.rb:15:in `extract_options!'
            from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:582:in `find'
            from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/associations/association_collection.rb:60:in `find'
            from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/associations/association_collection.rb:390:in `find_target'
            from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/associations/association_collection.rb:344:in `load_target'
            from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/associations/association_proxy.rb:208:in `method_missing'
            from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/associations/association_collection.rb:361:in `method_missing'
            from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:2183:in `sanitize_sql_array'
            from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:2079:in `sanitize_sql'
            from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1441:in `merge_conditions'
            from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1439:in `each'
            from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1439:in `merge_conditions'
            from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1742:in `add_conditions!'
            from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1629:in `construct_finder_sql'
            from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1490:in `find_every'
            from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:589:in `find'
    ... 2690 levels...
            from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:2003:in `with_scope'
            from (__DELEGATION__):2:in `__send__'
            from (__DELEGATION__):2:in `with_scope'
            from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/named_scope.rb:169:in `method_missing'
            from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/named_scope.rb:177:in `load_found'
            from /usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/named_scope.rb:161:in `proxy_found'
            from (__DELEGATION__):2:in `inspect'
            from /usr/lib/ruby/1.8/irb.rb:302:in `output_value'
            from /usr/lib/ruby/1.8/irb.rb:151:in `eval_input'
            from /usr/lib/ruby/1.8/irb.rb:263:in `signal_status'
            from /usr/lib/ruby/1.8/irb.rb:147:in `eval_input'
            from /usr/lib/ruby/1.8/irb.rb:146:in `eval_input'
            from /usr/lib/ruby/1.8/irb.rb:70:in `start'
            from /usr/lib/ruby/1.8/irb.rb:69:in `catch'
            from /usr/lib/ruby/1.8/irb.rb:69:in `start'
            from /usr/bin/irb:13>> 
    >> bla = forum.topics
    => [#<Topic id: 1, title: "first topic of the year", forum_id: 1, created_at: "2008-12-11 14:29:39", updated_at: "2008-12-11 14:29:39">, #<Topic id: 2, title: "second one", forum_id: 1, created_at: "2008-12-11 14:30:40", updated_at: "2008-12-11 14:30:40">]
    >> Topic.untracked(bla)
    => []
    >> Topic.untracked(forum.topics)
    => []
    >>
    

    December 11th, 2008 @ 02:44 PM

  7. Pratik
    Pratik
    • State changed from new to invalid
    • Assigned user set to Frederick Cheung

    Don't think it's a bug. Could you please submit a failing test if you think it's a bug ? http://guides.rails.info/contrib... should be helpful !

    Thanks.

    March 12th, 2009 @ 03:53 PM