ambition 0.3.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Manifest +41 -48
- data/README +6 -203
- data/ambition.gemspec +111 -0
- data/app_generators/ambition_adapter/USAGE +1 -0
- data/app_generators/ambition_adapter/ambition_adapter_generator.rb +66 -0
- data/app_generators/ambition_adapter/templates/LICENSE +18 -0
- data/app_generators/ambition_adapter/templates/README +6 -0
- data/app_generators/ambition_adapter/templates/Rakefile +31 -0
- data/app_generators/ambition_adapter/templates/lib/base.rb.erb +12 -0
- data/app_generators/ambition_adapter/templates/lib/init.rb.erb +22 -0
- data/app_generators/ambition_adapter/templates/lib/query.rb.erb +52 -0
- data/app_generators/ambition_adapter/templates/lib/select.rb.erb +100 -0
- data/app_generators/ambition_adapter/templates/lib/slice.rb.erb +19 -0
- data/app_generators/ambition_adapter/templates/lib/sort.rb.erb +43 -0
- data/app_generators/ambition_adapter/templates/test/helper.rb.erb +9 -0
- data/app_generators/ambition_adapter/templates/test/select_test.rb.erb +157 -0
- data/app_generators/ambition_adapter/templates/test/slice_test.rb.erb +36 -0
- data/app_generators/ambition_adapter/templates/test/sort_test.rb.erb +53 -0
- data/bin/ambition_adapter +13 -0
- data/lib/ambition.rb +8 -13
- data/lib/ambition/api.rb +42 -35
- data/lib/ambition/context.rb +62 -0
- data/lib/ambition/{proc_to_ruby.rb → core_ext.rb} +13 -0
- data/lib/ambition/enumerable.rb +6 -0
- data/lib/ambition/processors/base.rb +126 -0
- data/lib/ambition/processors/ruby.rb +24 -0
- data/lib/ambition/processors/select.rb +105 -0
- data/lib/ambition/processors/slice.rb +15 -0
- data/lib/ambition/processors/sort.rb +51 -0
- data/test/adapters/exemplar/association_test.rb +34 -0
- data/test/adapters/exemplar/count_test.rb +0 -0
- data/test/adapters/exemplar/detect_test.rb +9 -0
- data/test/adapters/exemplar/enumerable_test.rb +0 -0
- data/test/adapters/exemplar/helper.rb +3 -0
- data/test/adapters/exemplar/index_operator.rb +6 -0
- data/test/adapters/exemplar/reject_test.rb +0 -0
- data/test/adapters/exemplar/select_test.rb +151 -0
- data/test/adapters/exemplar/slice_test.rb +0 -0
- data/test/adapters/exemplar/sort_test.rb +0 -0
- data/test/debug +9 -0
- data/test/helper.rb +2 -52
- metadata +56 -71
- data/Rakefile +0 -64
- data/init.rb +0 -1
- data/lib/ambition/database_statements.rb +0 -31
- data/lib/ambition/processor.rb +0 -123
- data/lib/ambition/query.rb +0 -91
- data/lib/ambition/ruby_processor.rb +0 -22
- data/lib/ambition/select_processor.rb +0 -149
- data/lib/ambition/simple_processor.rb +0 -10
- data/lib/ambition/sort_processor.rb +0 -47
- data/lib/ambition/source.rb +0 -53
- data/test/benchmark.rb +0 -68
- data/test/chaining_test.rb +0 -34
- data/test/console +0 -9
- data/test/count_test.rb +0 -17
- data/test/databases/boot.rb +0 -3
- data/test/databases/database.yml +0 -17
- data/test/databases/fixtures/admin.rb +0 -3
- data/test/databases/fixtures/companies.yml +0 -24
- data/test/databases/fixtures/company.rb +0 -23
- data/test/databases/fixtures/developer.rb +0 -11
- data/test/databases/fixtures/developers_projects.yml +0 -13
- data/test/databases/fixtures/project.rb +0 -4
- data/test/databases/fixtures/projects.yml +0 -7
- data/test/databases/fixtures/replies.yml +0 -20
- data/test/databases/fixtures/reply.rb +0 -5
- data/test/databases/fixtures/topic.rb +0 -19
- data/test/databases/fixtures/topics.yml +0 -32
- data/test/databases/fixtures/user.rb +0 -2
- data/test/databases/fixtures/users.yml +0 -35
- data/test/databases/lib/activerecord_test_connector.rb +0 -65
- data/test/databases/lib/load_fixtures.rb +0 -13
- data/test/databases/lib/schema.rb +0 -41
- data/test/enumerable_test.rb +0 -95
- data/test/join_test.rb +0 -61
- data/test/limit_test.rb +0 -41
- data/test/order_test.rb +0 -52
- data/test/profiler.rb +0 -34
- data/test/ruby_test.rb +0 -9
- data/test/source_test.rb +0 -43
- data/test/types_test.rb +0 -59
- data/test/where_test.rb +0 -245
@@ -1,24 +0,0 @@
|
|
1
|
-
thirty_seven_signals:
|
2
|
-
id: 1
|
3
|
-
name: 37Signals
|
4
|
-
rating: 4
|
5
|
-
|
6
|
-
TextDrive:
|
7
|
-
id: 2
|
8
|
-
name: TextDrive
|
9
|
-
rating: 3
|
10
|
-
|
11
|
-
PlanetArgon:
|
12
|
-
id: 3
|
13
|
-
name: Planet Argon
|
14
|
-
rating: 3
|
15
|
-
|
16
|
-
Google:
|
17
|
-
id: 4
|
18
|
-
name: Google
|
19
|
-
rating: 5
|
20
|
-
|
21
|
-
Ionist:
|
22
|
-
id: 5
|
23
|
-
name: Ioni.st
|
24
|
-
rating: 4
|
@@ -1,23 +0,0 @@
|
|
1
|
-
class Company < ActiveRecord::Base
|
2
|
-
attr_protected :rating
|
3
|
-
set_sequence_name :companies_nonstd_seq
|
4
|
-
|
5
|
-
validates_presence_of :name
|
6
|
-
def validate
|
7
|
-
errors.add('rating', 'rating should not be 2') if rating == 2
|
8
|
-
end
|
9
|
-
|
10
|
-
def self.with_best
|
11
|
-
with_scope :find => { :conditions => ['companies.rating > ?', 3] } do
|
12
|
-
yield
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.find_best(*args)
|
17
|
-
with_best { find(*args) }
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.calculate_best(*args)
|
21
|
-
with_best { calculate(*args) }
|
22
|
-
end
|
23
|
-
end
|
@@ -1,11 +0,0 @@
|
|
1
|
-
class Developer < User
|
2
|
-
has_and_belongs_to_many :projects, :include => :topics, :order => 'projects.name'
|
3
|
-
|
4
|
-
def self.with_poor_ones(&block)
|
5
|
-
with_scope :find => { :conditions => ['salary <= ?', 80000], :order => 'salary' } do
|
6
|
-
yield
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
def self.per_page() 10 end
|
11
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
witty_retort:
|
2
|
-
id: 1
|
3
|
-
topic_id: 1
|
4
|
-
content: Birdman is better!
|
5
|
-
created_at: <%= 6.hours.ago.to_s(:db) %>
|
6
|
-
updated_at: nil
|
7
|
-
|
8
|
-
another:
|
9
|
-
id: 2
|
10
|
-
topic_id: 2
|
11
|
-
content: Nuh uh!
|
12
|
-
created_at: <%= 1.hour.ago.to_s(:db) %>
|
13
|
-
updated_at: nil
|
14
|
-
|
15
|
-
spam:
|
16
|
-
id: 3
|
17
|
-
topic_id: 1
|
18
|
-
content: Nice site!
|
19
|
-
created_at: <%= 1.hour.ago.to_s(:db) %>
|
20
|
-
updated_at: nil
|
@@ -1,19 +0,0 @@
|
|
1
|
-
class Topic < ActiveRecord::Base
|
2
|
-
has_many :replies, :dependent => :destroy, :order => 'replies.created_at DESC'
|
3
|
-
belongs_to :project
|
4
|
-
|
5
|
-
# pretend find and count were extended and accept an extra option
|
6
|
-
# if there is a :foo option, prepend its value to collection
|
7
|
-
def self.find(*args)
|
8
|
-
more = []
|
9
|
-
more << args.last.delete(:foo) if args.last.is_a?(Hash) and args.last[:foo]
|
10
|
-
res = super
|
11
|
-
more.empty?? res : more + res
|
12
|
-
end
|
13
|
-
|
14
|
-
# if there is a :foo option, always return 100
|
15
|
-
def self.count(*args)
|
16
|
-
return 100 if args.last.is_a?(Hash) and args.last[:foo]
|
17
|
-
super
|
18
|
-
end
|
19
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
futurama:
|
2
|
-
id: 1
|
3
|
-
title: Isnt futurama awesome?
|
4
|
-
subtitle: It really is, isnt it.
|
5
|
-
content: I like futurama
|
6
|
-
created_at: <%= 1.day.ago.to_s(:db) %>
|
7
|
-
updated_at: <%= 1.day.ago.to_s(:db) %>
|
8
|
-
|
9
|
-
harvey_birdman:
|
10
|
-
id: 2
|
11
|
-
title: Harvey Birdman is the king of all men
|
12
|
-
subtitle: yup
|
13
|
-
content: He really is
|
14
|
-
created_at: <%= 2.hours.ago.to_s(:db) %>
|
15
|
-
updated_at: <%= 2.hours.ago.to_s(:db) %>
|
16
|
-
|
17
|
-
rails:
|
18
|
-
id: 3
|
19
|
-
project_id: 1
|
20
|
-
title: Rails is nice
|
21
|
-
subtitle: It makes me happy
|
22
|
-
content: except when I have to hack internals to fix pagination. even then really.
|
23
|
-
created_at: <%= 20.minutes.ago.to_s(:db) %>
|
24
|
-
updated_at: <%= 20.minutes.ago.to_s(:db) %>
|
25
|
-
|
26
|
-
ar:
|
27
|
-
id: 4
|
28
|
-
project_id: 1
|
29
|
-
title: ActiveRecord sometimes freaks me out
|
30
|
-
content: "I mean, what's the deal with eager loading?"
|
31
|
-
created_at: <%= 15.minutes.ago.to_s(:db) %>
|
32
|
-
updated_at: <%= 15.minutes.ago.to_s(:db) %>
|
@@ -1,35 +0,0 @@
|
|
1
|
-
david:
|
2
|
-
id: 1
|
3
|
-
name: David
|
4
|
-
salary: 80000
|
5
|
-
type: Developer
|
6
|
-
|
7
|
-
jamis:
|
8
|
-
id: 2
|
9
|
-
name: Jamis
|
10
|
-
salary: 150000
|
11
|
-
type: Developer
|
12
|
-
|
13
|
-
<% for digit in 3..10 %>
|
14
|
-
dev_<%= digit %>:
|
15
|
-
id: <%= digit %>
|
16
|
-
name: fixture_<%= digit %>
|
17
|
-
salary: 100000
|
18
|
-
type: Developer
|
19
|
-
<% end %>
|
20
|
-
|
21
|
-
poor_jamis:
|
22
|
-
id: 11
|
23
|
-
name: Jamis
|
24
|
-
salary: 9000
|
25
|
-
type: Developer
|
26
|
-
|
27
|
-
admin:
|
28
|
-
id: 12
|
29
|
-
name: admin
|
30
|
-
type: Admin
|
31
|
-
|
32
|
-
goofy:
|
33
|
-
id: 13
|
34
|
-
name: Goofy
|
35
|
-
type: Admin
|
@@ -1,65 +0,0 @@
|
|
1
|
-
class ActiveRecordTestConnector
|
2
|
-
cattr_accessor :able_to_connect
|
3
|
-
cattr_accessor :connected
|
4
|
-
|
5
|
-
# Set our defaults
|
6
|
-
self.connected = false
|
7
|
-
self.able_to_connect = true
|
8
|
-
|
9
|
-
def self.setup
|
10
|
-
unless connected || !able_to_connect
|
11
|
-
setup_connection
|
12
|
-
load_schema
|
13
|
-
require_fixture_models
|
14
|
-
self.connected = true
|
15
|
-
end
|
16
|
-
rescue Exception => e # errors from ActiveRecord setup
|
17
|
-
if e.to_s =~ /unknown database/i
|
18
|
-
puts "\nPlease create an `ambition_development' database to play!"
|
19
|
-
else
|
20
|
-
$stderr.puts "\nSkipping ActiveRecord assertion tests: #{e}"
|
21
|
-
end
|
22
|
-
self.able_to_connect = false
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def self.setup_connection
|
28
|
-
if Object.const_defined?(:ActiveRecord)
|
29
|
-
config_file = File.dirname(__FILE__) + '/../database.yml'
|
30
|
-
ActiveRecord::Base.logger = Logger.new STDOUT
|
31
|
-
|
32
|
-
case adapter = ENV['ADAPTER'] || 'mysql'
|
33
|
-
when 'sqlite3'
|
34
|
-
options = { :database => ':memory:', :adapter => 'sqlite3', :timeout => 500 }
|
35
|
-
ActiveRecord::Base.configurations = { 'sqlite3_ar_integration' => options }
|
36
|
-
else
|
37
|
-
options = YAML.load_file(config_file)[adapter]
|
38
|
-
end
|
39
|
-
|
40
|
-
puts "Using #{adapter}"
|
41
|
-
|
42
|
-
ActiveRecord::Base.establish_connection(options)
|
43
|
-
ActiveRecord::Base.connection
|
44
|
-
|
45
|
-
unless Object.const_defined?(:QUOTED_TYPE)
|
46
|
-
Object.send :const_set, :QUOTED_TYPE, ActiveRecord::Base.connection.quote_column_name('type')
|
47
|
-
end
|
48
|
-
else
|
49
|
-
raise "Can't setup connection since ActiveRecord isn't loaded."
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
# Load actionpack sqlite tables
|
54
|
-
def self.load_schema
|
55
|
-
ActiveRecord::Base.silence do
|
56
|
-
load File.dirname(__FILE__) + "/schema.rb"
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def self.require_fixture_models
|
61
|
-
models = Dir.glob(File.dirname(__FILE__) + "/../fixtures/*.rb")
|
62
|
-
models = (models.grep(/user.rb/) + models).uniq
|
63
|
-
models.each {|f| require f}
|
64
|
-
end
|
65
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
dirname = File.dirname(__FILE__)
|
2
|
-
%w(rubygems active_record active_record/version active_record/fixtures).each {|f| require f}
|
3
|
-
puts " (ActiveRecord v#{ActiveRecord::VERSION::STRING})"
|
4
|
-
require File.join(dirname, 'activerecord_test_connector')
|
5
|
-
|
6
|
-
# setup the connection
|
7
|
-
ActiveRecordTestConnector.setup
|
8
|
-
|
9
|
-
# load all fixtures
|
10
|
-
fixture_path = File.join(dirname, '..', 'fixtures')
|
11
|
-
Fixtures.create_fixtures(fixture_path, tables = ActiveRecord::Base.connection.tables - %w(schema_info))
|
12
|
-
|
13
|
-
puts "Available models: #{Dir[fixture_path+'/*.rb'].map{|f|File.basename(f,'.rb')}.map(&:classify).to_sentence}"
|
@@ -1,41 +0,0 @@
|
|
1
|
-
ActiveRecord::Schema.define(:version => 0) do
|
2
|
-
create_table :users, :force => true do |t|
|
3
|
-
t.column :name, :string
|
4
|
-
t.column :type, :string
|
5
|
-
t.column :salary, :integer, :default => 70_000
|
6
|
-
t.column :created_at, :datetime, :null => false
|
7
|
-
t.column :updated_at, :datetime, :null => false
|
8
|
-
end
|
9
|
-
|
10
|
-
create_table :replies, :force => true do |t|
|
11
|
-
t.column :content, :string
|
12
|
-
t.column :topic_id, :integer
|
13
|
-
t.column :created_at, :datetime, :null => false
|
14
|
-
t.column :updated_at, :datetime, :null => false
|
15
|
-
end
|
16
|
-
|
17
|
-
create_table :topics, :force => true do |t|
|
18
|
-
t.column :project_id, :integer
|
19
|
-
t.column :title, :string
|
20
|
-
t.column :subtitle, :string
|
21
|
-
t.column :content, :text
|
22
|
-
t.column :created_at, :datetime, :null => false
|
23
|
-
t.column :updated_at, :datetime, :null => false
|
24
|
-
end
|
25
|
-
|
26
|
-
create_table :projects, :force => true do |t|
|
27
|
-
t.column :name, :string
|
28
|
-
end
|
29
|
-
|
30
|
-
create_table :developers_projects, :force => true do |t|
|
31
|
-
t.column :developer_id, :integer
|
32
|
-
t.column :project_id, :integer
|
33
|
-
t.column :joined_on, :datetime
|
34
|
-
t.column :access_level, :integer, :default => 1
|
35
|
-
end
|
36
|
-
|
37
|
-
create_table :companies, :force => true do |t|
|
38
|
-
t.column :name, :string
|
39
|
-
t.column :rating, :integer
|
40
|
-
end
|
41
|
-
end
|
data/test/enumerable_test.rb
DELETED
@@ -1,95 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/helper'
|
2
|
-
|
3
|
-
context "Each" do
|
4
|
-
specify "simple ==" do
|
5
|
-
hash = { :conditions => "users.age = 21" }
|
6
|
-
User.expects(:find).with(:all, hash).returns([])
|
7
|
-
User.select { |m| m.age == 21 }.each do |user|
|
8
|
-
puts user.name
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
specify "limit and conditions" do
|
13
|
-
hash = { :limit => 5, :conditions => "users.age = 21" }
|
14
|
-
User.expects(:find).with(:all, hash).returns([])
|
15
|
-
User.select { |m| m.age == 21 }.first(5).each do |user|
|
16
|
-
puts user.name
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
specify "limit and conditions and order" do
|
21
|
-
hash = { :limit => 5, :conditions => "users.age = 21", :order => 'users.name' }
|
22
|
-
User.expects(:find).with(:all, hash).returns([])
|
23
|
-
User.select { |m| m.age == 21 }.sort_by { |m| m.name }.first(5).each do |user|
|
24
|
-
puts user.name
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
specify "limit and order" do
|
29
|
-
hash = { :limit => 5, :order => 'users.name' }
|
30
|
-
User.expects(:find).with(:all, hash).returns([])
|
31
|
-
User.sort_by { |m| m.name }.first(5).each do |user|
|
32
|
-
puts user.name
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
context "Enumerable Methods" do
|
38
|
-
specify "map" do
|
39
|
-
hash = { :conditions => "users.age = 21" }
|
40
|
-
User.expects(:find).with(:all, hash).returns([])
|
41
|
-
User.select { |m| m.age == 21 }.map { |u| u.name }
|
42
|
-
end
|
43
|
-
|
44
|
-
specify "each_with_index" do
|
45
|
-
hash = { :conditions => "users.age = 21" }
|
46
|
-
User.expects(:find).with(:all, hash).returns([])
|
47
|
-
User.select { |m| m.age == 21 }.each_with_index do |user, i|
|
48
|
-
puts "#{i}: #{user.name}"
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
specify "any?" do
|
53
|
-
User.expects(:count).with(:conditions => "users.age > 21").returns(1)
|
54
|
-
User.any? { |u| u.age > 21 }.should == true
|
55
|
-
end
|
56
|
-
|
57
|
-
specify "all?" do
|
58
|
-
User.expects(:count).at_least_once.returns(10, 20)
|
59
|
-
User.all? { |u| u.age > 21 }.should == false
|
60
|
-
|
61
|
-
User.expects(:count).at_least_once.returns(10, 10)
|
62
|
-
User.all? { |u| u.age > 21 }.should == true
|
63
|
-
end
|
64
|
-
|
65
|
-
specify "empty?" do
|
66
|
-
User.expects(:count).with(:conditions => "users.age > 21").returns(1)
|
67
|
-
User.select { |u| u.age > 21 }.empty?.should.equal false
|
68
|
-
|
69
|
-
User.expects(:count).with(:conditions => "users.age > 21").returns(0)
|
70
|
-
User.select { |u| u.age > 21 }.empty?.should.equal true
|
71
|
-
end
|
72
|
-
|
73
|
-
specify "entries" do
|
74
|
-
User.expects(:find).with(:all, {})
|
75
|
-
User.entries
|
76
|
-
|
77
|
-
hash = { :conditions => "users.age = 21" }
|
78
|
-
User.expects(:find).with(:all, hash).returns([])
|
79
|
-
User.select { |m| m.age == 21 }.entries
|
80
|
-
end
|
81
|
-
|
82
|
-
specify "to_a" do
|
83
|
-
User.expects(:find).with(:all, {})
|
84
|
-
User.to_a
|
85
|
-
end
|
86
|
-
|
87
|
-
xspecify "each_slice" do
|
88
|
-
end
|
89
|
-
|
90
|
-
xspecify "max" do
|
91
|
-
end
|
92
|
-
|
93
|
-
xspecify "min" do
|
94
|
-
end
|
95
|
-
end
|
data/test/join_test.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/helper'
|
2
|
-
|
3
|
-
context "Joins" do
|
4
|
-
specify "simple == on an association" do
|
5
|
-
sql = User.select { |m| m.account.email == 'chris@ozmm.org' }
|
6
|
-
sql.to_hash.should == {
|
7
|
-
:conditions => "accounts.email = 'chris@ozmm.org'",
|
8
|
-
:include => [:account]
|
9
|
-
}
|
10
|
-
end
|
11
|
-
|
12
|
-
specify "simple mixed == on an association" do
|
13
|
-
sql = User.select { |m| m.name == 'chris' && m.account.email == 'chris@ozmm.org' }
|
14
|
-
sql.to_hash.should == {
|
15
|
-
:conditions => "(users.name = 'chris' AND accounts.email = 'chris@ozmm.org')",
|
16
|
-
:include => [:account]
|
17
|
-
}
|
18
|
-
end
|
19
|
-
|
20
|
-
specify "multiple associations" do
|
21
|
-
sql = User.select { |m| m.ideas.title == 'New Freezer' || m.invites.email == 'pj@hyett.com' }
|
22
|
-
sql.to_hash.should == {
|
23
|
-
:conditions => "(ideas.title = 'New Freezer' OR invites.email = 'pj@hyett.com')",
|
24
|
-
:include => [:ideas, :invites]
|
25
|
-
}
|
26
|
-
end
|
27
|
-
|
28
|
-
specify "belongs_to" do
|
29
|
-
sql = User.select { |m| m.account.id > 20 }
|
30
|
-
sql.to_hash.should == {
|
31
|
-
:conditions => "accounts.id > 20",
|
32
|
-
:include => [:account]
|
33
|
-
}
|
34
|
-
end
|
35
|
-
|
36
|
-
specify "complex joins have no to_s" do
|
37
|
-
sql = User.select { |m| m.account.id > 20 }
|
38
|
-
should.raise { sql.to_s }
|
39
|
-
end
|
40
|
-
|
41
|
-
specify "non-existant associations" do
|
42
|
-
sql = User.select { |m| m.liquor.brand == 'Jack' }
|
43
|
-
should.raise { sql.to_hash }
|
44
|
-
end
|
45
|
-
|
46
|
-
specify "in order" do
|
47
|
-
sql = User.sort_by { |m| m.ideas.title }
|
48
|
-
sql.to_hash.should == {
|
49
|
-
:order => "ideas.title",
|
50
|
-
:include => [:ideas]
|
51
|
-
}
|
52
|
-
end
|
53
|
-
|
54
|
-
specify "in a more complex order" do
|
55
|
-
sql = User.sort_by { |m| [ m.ideas.title, -m.invites.email ] }
|
56
|
-
sql.to_hash.should == {
|
57
|
-
:order => "ideas.title, invites.email DESC",
|
58
|
-
:include => [:ideas, :invites]
|
59
|
-
}
|
60
|
-
end
|
61
|
-
end
|