From 7d33b99783bf2bbf70d9cebe144467dbdacc44ee Mon Sep 17 00:00:00 2001 From: toby cabot Date: Fri, 12 Nov 2010 08:52:22 -0500 Subject: [PATCH] allow query scopes to handle methods that return a single model If you do this (which is an easy mistake for a newbie like me to make): module RailsAdmin class History < ActiveRecord::Base scope :most_recent, lambda {|table| where("tbl = ?", table).order("updated_at").last } ... (Note the call to "last" at the end of the lambda) you get this: ruby-1.8.7-p302 > RailsAdmin::History.most_recent("Team") NoMethodError: undefined method `includes_values' for # from {snip}/activemodel-3.0.1/lib/active_model/attribute_methods.rb:364:in `method_missing' from {snip}/activerecord-3.0.1/lib/active_record/attribute_methods.rb:46:in `method_missing' from {snip}/activerecord-3.0.1/lib/active_record/attribute_methods.rb:44:in `send' from {snip}/activerecord-3.0.1/lib/active_record/attribute_methods.rb:44:in `method_missing' from {snip}/activerecord-3.0.1/lib/active_recrd/relation/spawn_methods.rb:10:in `send' from {snip}/activerecord-3.0.1/lib/active_record/relation/spawn_methods.rb:10:in `merge' from {snip}/activerecord-3.0.1/lib/active_record/relation/spawn_methods.rb:9:in `each' from {snip}/activerecord-3.0.1/lib/active_record/relation/spawn_methods.rb:9:in `merge' from {snip}/activerecord-3.0.1/lib/active_record/named_scope.rb:112:in `most_recent' from (irb):3 This happens because spawn_methods.merge() is trying to merge a Relation with an ActiveRecord model object (the result of the last() method at the end of the scope). This change adds a case to the named scope processing to handle the case where the result of the scope is a single activerecord object instead of a Relation. --- activerecord/lib/active_record/named_scope.rb | 2 ++ activerecord/test/cases/named_scope_test.rb | 4 ++++ activerecord/test/models/post.rb | 1 + 3 files changed, 7 insertions(+), 0 deletions(-) diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb index 0b92ba5..0b8c8b8 100644 --- a/activerecord/lib/active_record/named_scope.rb +++ b/activerecord/lib/active_record/named_scope.rb @@ -108,6 +108,8 @@ module ActiveRecord relation = if options.is_a?(Hash) scoped.apply_finder_options(options) + elsif options.is_a?(ActiveRecord::Base) + options elsif options scoped.merge(options) else diff --git a/activerecord/test/cases/named_scope_test.rb b/activerecord/test/cases/named_scope_test.rb index fb24c65..b8e902e 100644 --- a/activerecord/test/cases/named_scope_test.rb +++ b/activerecord/test/cases/named_scope_test.rb @@ -361,6 +361,10 @@ class NamedScopeTest < ActiveRecord::TestCase assert_equal [posts(:sti_comments)], Post.with_special_comments.with_post(4).all.uniq end + def test_named_scopes_that_return_a_single_instance + assert_equal Post.order("comments_count DESC").last, Post.most_commented + end + def test_named_scopes_batch_finders assert_equal 3, Topic.approved.count diff --git a/activerecord/test/models/post.rb b/activerecord/test/models/post.rb index 61e782f..4d50d38 100644 --- a/activerecord/test/models/post.rb +++ b/activerecord/test/models/post.rb @@ -13,6 +13,7 @@ class Post < ActiveRecord::Base :joins => 'JOIN authors ON authors.id = posts.author_id' } } + scope :most_commented, lambda { ranked_by_comments.last } belongs_to :author do def greeting -- 1.7.0.4