From a7915495880ae091b626e8b313c5c75f1f6fbf36 Mon Sep 17 00:00:00 2001 From: Norman Clarke Date: Thu, 23 Oct 2008 21:40:22 -0200 Subject: [PATCH] Added support for :order => :random in queries. --- activerecord/lib/active_record/base.rb | 6 +++--- .../connection_adapters/abstract_adapter.rb | 14 ++++++++++++++ .../connection_adapters/mysql_adapter.rb | 10 +++++++++- activerecord/test/cases/finder_test.rb | 5 +++++ activerecord/test/cases/named_scope_test.rb | 5 +++++ 5 files changed, 36 insertions(+), 4 deletions(-) diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index b89c864..f5b3017 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1669,10 +1669,10 @@ module ActiveRecord #:nodoc: scope = scope(:find) if :auto == scope scoped_order = scope[:order] if scope if order - sql << " ORDER BY #{order}" - sql << ", #{scoped_order}" if scoped_order + sql << " ORDER BY #{connection.order(order)}" + sql << ", #{connection.order(scoped_order)}" if scoped_order else - sql << " ORDER BY #{scoped_order}" if scoped_order + sql << " ORDER BY #{connection.order(scoped_order)}" if scoped_order end end diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index c518335..8d6a247 100755 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -93,6 +93,20 @@ module ActiveRecord yield end + # DATABASE STATEMENTS ====================================== + + # Adjust ORDER BY arguments to match supported syntax. Passing :random + # will return the appropriate RAND()/RANDOM()/etc for the adapter. All + # other arguments are returned unmodified. + def order(arg) + case arg + when :random + "RANDOM()" + else + arg + end + end + # CONNECTION MANAGEMENT ==================================== # Checks whether the connection to the database is still active. This includes diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb index 1e452ae..a43b306 100644 --- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb @@ -354,7 +354,15 @@ module ActiveRecord end end end - + + def order(arg) + case arg + when :random + "RAND()" + else + arg + end + end # SCHEMA STATEMENTS ======================================== diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index 153880a..5722bc9 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -175,6 +175,11 @@ class FinderTest < ActiveRecord::TestCase assert_equal 4, developers.map(&:salary).uniq.size end + def test_find_with_random_order + developers = Developer.find(:all, :order => :random, :limit => 4) + assert_equal 4, developers.size + end + def test_find_with_entire_select_statement topics = Topic.find_by_sql "SELECT * FROM topics WHERE author_name = 'Mary'" diff --git a/activerecord/test/cases/named_scope_test.rb b/activerecord/test/cases/named_scope_test.rb index 64e8997..67c434d 100644 --- a/activerecord/test/cases/named_scope_test.rb +++ b/activerecord/test/cases/named_scope_test.rb @@ -158,6 +158,11 @@ class NamedScopeTest < ActiveRecord::TestCase expected_proxy_options = { :conditions => { :approved => true } } assert_equal expected_proxy_options, Topic.approved.proxy_options end + + def test_random_order + topics = Topic.base.all(:order => :random, :limit => 4) + assert_equal 4, topics.size + end def test_first_and_last_should_support_find_options assert_equal Topic.base.first(:order => 'title'), Topic.base.find(:first, :order => 'title') -- 1.6.0