aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record.rb1
-rwxr-xr-xactiverecord/lib/active_record/associations.rb4
-rw-r--r--activerecord/lib/active_record/associations/association_proxy.rb4
-rwxr-xr-xactiverecord/lib/active_record/base.rb5
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb41
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb10
-rw-r--r--activerecord/lib/active_record/serializers/json_serializer.rb2
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb6
-rw-r--r--activerecord/test/cases/associations/inner_join_association_test.rb5
-rwxr-xr-xactiverecord/test/cases/base_test.rb4
-rw-r--r--activerecord/test/cases/copy_table_test_sqlite.rb10
-rw-r--r--activerecord/test/cases/schema_dumper_test.rb10
-rw-r--r--activerecord/test/cases/schema_test_postgresql.rb32
-rw-r--r--activerecord/test/models/author.rb2
-rw-r--r--activerecord/test/models/company.rb13
-rw-r--r--activerecord/test/models/project.rb2
-rw-r--r--activerecord/test/schema/schema.rb6
17 files changed, 117 insertions, 40 deletions
diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb
index 2f8c5c712f..500a90d6cb 100644
--- a/activerecord/lib/active_record.rb
+++ b/activerecord/lib/active_record.rb
@@ -30,6 +30,7 @@ rescue LoadError
require 'active_support'
end
end
+require 'active_support/core/all'
module ActiveRecord
# TODO: Review explicit loads to see if they will automatically be handled by the initilizer.
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index 53a710537f..2115878e32 100755
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -1375,7 +1375,7 @@ module ActiveRecord
dependent_conditions = []
dependent_conditions << "#{reflection.primary_key_name} = \#{record.quoted_id}"
dependent_conditions << "#{reflection.options[:as]}_type = '#{base_class.name}'" if reflection.options[:as]
- dependent_conditions << sanitize_sql(reflection.options[:conditions]) if reflection.options[:conditions]
+ dependent_conditions << sanitize_sql(reflection.options[:conditions], reflection.quoted_table_name) if reflection.options[:conditions]
dependent_conditions << extra_conditions if extra_conditions
dependent_conditions = dependent_conditions.collect {|where| "(#{where})" }.join(" AND ")
dependent_conditions = dependent_conditions.gsub('@', '\@')
@@ -2123,7 +2123,7 @@ module ActiveRecord
klass.send(:type_condition, aliased_table_name)] unless klass.descends_from_active_record?
[through_reflection, reflection].each do |ref|
- join << "AND #{interpolate_sql(sanitize_sql(ref.options[:conditions]))} " if ref && ref.options[:conditions]
+ join << "AND #{interpolate_sql(sanitize_sql(ref.options[:conditions], aliased_table_name))} " if ref && ref.options[:conditions]
end
join
diff --git a/activerecord/lib/active_record/associations/association_proxy.rb b/activerecord/lib/active_record/associations/association_proxy.rb
index 676c4ace61..241b9bfee0 100644
--- a/activerecord/lib/active_record/associations/association_proxy.rb
+++ b/activerecord/lib/active_record/associations/association_proxy.rb
@@ -169,8 +169,8 @@ module ActiveRecord
end
# Forwards the call to the reflection class.
- def sanitize_sql(sql)
- @reflection.klass.send(:sanitize_sql, sql)
+ def sanitize_sql(sql, table_name = @reflection.klass.quoted_table_name)
+ @reflection.klass.send(:sanitize_sql, sql, table_name)
end
# Assigns the ID of the owner to the corresponding foreign key in +record+.
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 9943a7014a..97c36a675d 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -1,5 +1,6 @@
require 'yaml'
require 'set'
+require 'active_support/dependencies'
module ActiveRecord #:nodoc:
# Generic Active Record exception class.
@@ -2231,12 +2232,12 @@ module ActiveRecord #:nodoc:
# ["name='%s' and group_id='%s'", "foo'bar", 4] returns "name='foo''bar' and group_id='4'"
# { :name => "foo'bar", :group_id => 4 } returns "name='foo''bar' and group_id='4'"
# "name='foo''bar' and group_id='4'" returns "name='foo''bar' and group_id='4'"
- def sanitize_sql_for_conditions(condition)
+ def sanitize_sql_for_conditions(condition, table_name = quoted_table_name)
return nil if condition.blank?
case condition
when Array; sanitize_sql_array(condition)
- when Hash; sanitize_sql_hash_for_conditions(condition)
+ when Hash; sanitize_sql_hash_for_conditions(condition, table_name)
else condition
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index ec204d0f03..4961793866 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -640,33 +640,36 @@ module ActiveRecord
def indexes(table_name, name = nil)
schemas = schema_search_path.split(/,/).map { |p| quote(p) }.join(',')
result = query(<<-SQL, name)
- SELECT distinct i.relname, d.indisunique, a.attname
- FROM pg_class t, pg_class i, pg_index d, pg_attribute a
+ SELECT distinct i.relname, d.indisunique, d.indkey, t.oid
+ FROM pg_class t, pg_class i, pg_index d
WHERE i.relkind = 'i'
AND d.indexrelid = i.oid
AND d.indisprimary = 'f'
AND t.oid = d.indrelid
AND t.relname = '#{table_name}'
AND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname IN (#{schemas}) )
- AND a.attrelid = t.oid
- AND ( d.indkey[0]=a.attnum OR d.indkey[1]=a.attnum
- OR d.indkey[2]=a.attnum OR d.indkey[3]=a.attnum
- OR d.indkey[4]=a.attnum OR d.indkey[5]=a.attnum
- OR d.indkey[6]=a.attnum OR d.indkey[7]=a.attnum
- OR d.indkey[8]=a.attnum OR d.indkey[9]=a.attnum )
ORDER BY i.relname
SQL
- current_index = nil
+
indexes = []
- result.each do |row|
- if current_index != row[0]
- indexes << IndexDefinition.new(table_name, row[0], row[1] == "t", [])
- current_index = row[0]
- end
+ indexes = result.map do |row|
+ index_name = row[0]
+ unique = row[1] == 't'
+ indkey = row[2].split(" ")
+ oid = row[3]
+
+ columns = query(<<-SQL, "Columns for index #{row[0]} on #{table_name}").inject({}) {|attlist, r| attlist[r[1]] = r[0]; attlist}
+ SELECT a.attname, a.attnum
+ FROM pg_attribute a
+ WHERE a.attrelid = #{oid}
+ AND a.attnum IN (#{indkey.join(",")})
+ SQL
+
+ column_names = indkey.map {|attnum| columns[attnum] }
+ IndexDefinition.new(table_name, index_name, unique, column_names)
- indexes.last.columns << row[2]
end
indexes
@@ -764,7 +767,7 @@ module ActiveRecord
AND attr.attrelid = cons.conrelid
AND attr.attnum = cons.conkey[1]
AND cons.contype = 'p'
- AND dep.refobjid = '#{table}'::regclass
+ AND dep.refobjid = '#{quote_table_name(table)}'::regclass
end_sql
if result.nil? or result.empty?
@@ -783,7 +786,7 @@ module ActiveRecord
JOIN pg_attribute attr ON (t.oid = attrelid)
JOIN pg_attrdef def ON (adrelid = attrelid AND adnum = attnum)
JOIN pg_constraint cons ON (conrelid = adrelid AND adnum = conkey[1])
- WHERE t.oid = '#{table}'::regclass
+ WHERE t.oid = '#{quote_table_name(table)}'::regclass
AND cons.contype = 'p'
AND def.adsrc ~* 'nextval'
end_sql
@@ -858,7 +861,7 @@ module ActiveRecord
# Drops an index from a table.
def remove_index(table_name, options = {})
- execute "DROP INDEX #{index_name(table_name, options)}"
+ execute "DROP INDEX #{quote_table_name(index_name(table_name, options))}"
end
# Maps logical Rails types to PostgreSQL-specific data types.
@@ -1059,7 +1062,7 @@ module ActiveRecord
SELECT a.attname, format_type(a.atttypid, a.atttypmod), d.adsrc, a.attnotnull
FROM pg_attribute a LEFT JOIN pg_attrdef d
ON a.attrelid = d.adrelid AND a.attnum = d.adnum
- WHERE a.attrelid = '#{table_name}'::regclass
+ WHERE a.attrelid = '#{quote_table_name(table_name)}'::regclass
AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum
end_sql
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
index afd6472db8..05334a830a 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
@@ -150,6 +150,16 @@ module ActiveRecord
%Q("#{name}")
end
+ # Quote date/time values for use in SQL input. Includes microseconds
+ # if the value is a Time responding to usec.
+ def quoted_date(value) #:nodoc:
+ if value.acts_like?(:time) && value.respond_to?(:usec)
+ "#{super}.#{sprintf("%06d", value.usec)}"
+ else
+ super
+ end
+ end
+
# DATABASE STATEMENTS ======================================
diff --git a/activerecord/lib/active_record/serializers/json_serializer.rb b/activerecord/lib/active_record/serializers/json_serializer.rb
index 1fd65ed006..c709c3f1eb 100644
--- a/activerecord/lib/active_record/serializers/json_serializer.rb
+++ b/activerecord/lib/active_record/serializers/json_serializer.rb
@@ -1,3 +1,5 @@
+require 'active_support/json'
+
module ActiveRecord #:nodoc:
module Serialization
def self.included(base)
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index 30edf79a26..5df74fcdcd 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -719,6 +719,12 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert Client.find(:all, :conditions => "firm_id=#{firm.id}").empty?
end
+ def test_dependence_for_associations_with_hash_condition
+ david = authors(:david)
+ post = posts(:thinking).id
+ assert_difference('Post.count', -1) { assert david.destroy }
+ end
+
def test_destroy_dependent_when_deleted_from_association
firm = Firm.find(:first)
assert_equal 2, firm.clients.size
diff --git a/activerecord/test/cases/associations/inner_join_association_test.rb b/activerecord/test/cases/associations/inner_join_association_test.rb
index f87c914125..7141531740 100644
--- a/activerecord/test/cases/associations/inner_join_association_test.rb
+++ b/activerecord/test/cases/associations/inner_join_association_test.rb
@@ -29,6 +29,11 @@ class InnerJoinAssociationTest < ActiveRecord::TestCase
assert_match /INNER JOIN .?categories.? ON.*AND.*.?General.?.*TERMINATING_MARKER/, sql
end
+ def test_construct_finder_sql_applies_aliases_tables_on_association_conditions
+ result = Author.find(:all, :joins => [:thinking_posts, :welcome_posts])
+ assert_equal authors(:david), result.first
+ end
+
def test_construct_finder_sql_unpacks_nested_joins
sql = Author.send(:construct_finder_sql, :joins => {:posts => [[:comments]]})
assert_no_match /inner join.*inner join.*inner join/i, sql, "only two join clauses should be present"
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index 99d77961fc..d97cd17d75 100755
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -456,7 +456,7 @@ class BasicsTest < ActiveRecord::TestCase
)
# For adapters which support microsecond resolution.
- if current_adapter?(:PostgreSQLAdapter)
+ if current_adapter?(:PostgreSQLAdapter) || current_adapter?(:SQLiteAdapter)
assert_equal 11, Topic.find(1).written_on.sec
assert_equal 223300, Topic.find(1).written_on.usec
assert_equal 9900, Topic.find(2).written_on.usec
@@ -1756,7 +1756,7 @@ class BasicsTest < ActiveRecord::TestCase
end
def test_scoped_find_with_group_and_having
- developers = Developer.with_scope(:find => { :group => 'salary', :having => "SUM(salary) > 10000", :select => "SUM(salary) as salary" }) do
+ developers = Developer.with_scope(:find => { :group => 'developers.salary', :having => "SUM(salary) > 10000", :select => "SUM(salary) as salary" }) do
Developer.find(:all)
end
assert_equal 3, developers.size
diff --git a/activerecord/test/cases/copy_table_test_sqlite.rb b/activerecord/test/cases/copy_table_test_sqlite.rb
index 72bd7e2dab..de8af30997 100644
--- a/activerecord/test/cases/copy_table_test_sqlite.rb
+++ b/activerecord/test/cases/copy_table_test_sqlite.rb
@@ -10,7 +10,7 @@ class CopyTableTest < ActiveRecord::TestCase
end
end
- def test_copy_table(from = 'companies', to = 'companies2', options = {})
+ def test_copy_table(from = 'customers', to = 'customers2', options = {})
assert_nothing_raised {copy_table(from, to, options)}
assert_equal row_count(from), row_count(to)
@@ -24,11 +24,11 @@ class CopyTableTest < ActiveRecord::TestCase
end
def test_copy_table_renaming_column
- test_copy_table('companies', 'companies2',
- :rename => {'client_of' => 'fan_of'}) do |from, to, options|
- expected = column_values(from, 'client_of')
+ test_copy_table('customers', 'customers2',
+ :rename => {'name' => 'person_name'}) do |from, to, options|
+ expected = column_values(from, 'name')
assert expected.any?, 'only nils in resultset; real values are needed'
- assert_equal expected, column_values(to, 'fan_of')
+ assert_equal expected, column_values(to, 'person_name')
end
end
diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb
index 17e4c755ce..f9ad7f3ba3 100644
--- a/activerecord/test/cases/schema_dumper_test.rb
+++ b/activerecord/test/cases/schema_dumper_test.rb
@@ -22,6 +22,11 @@ class SchemaDumperTest < ActiveRecord::TestCase
assert_no_match %r{create_table "sqlite_sequence"}, output
end
+ def test_schema_dump_includes_camelcase_table_name
+ output = standard_dump
+ assert_match %r{create_table "CamelCase"}, output
+ end
+
def assert_line_up(lines, pattern, required = false)
return assert(true) if lines.empty?
matches = lines.map { |line| line.match(pattern) }
@@ -147,6 +152,11 @@ class SchemaDumperTest < ActiveRecord::TestCase
end
end
+ def test_schema_dumps_index_columns_in_right_order
+ index_definition = standard_dump.split(/\n/).grep(/add_index.*companies/).first.strip
+ assert_equal 'add_index "companies", ["firm_id", "type", "rating", "ruby_type"], :name => "company_index"', index_definition
+ end
+
if current_adapter?(:MysqlAdapter)
def test_schema_dump_should_not_add_default_value_for_mysql_text_field
output = standard_dump
diff --git a/activerecord/test/cases/schema_test_postgresql.rb b/activerecord/test/cases/schema_test_postgresql.rb
index 2d36bd0b22..a294848fa3 100644
--- a/activerecord/test/cases/schema_test_postgresql.rb
+++ b/activerecord/test/cases/schema_test_postgresql.rb
@@ -6,6 +6,7 @@ class SchemaTest < ActiveRecord::TestCase
SCHEMA_NAME = 'test_schema'
SCHEMA2_NAME = 'test_schema2'
TABLE_NAME = 'things'
+ CAPITALIZED_TABLE_NAME = 'Things'
INDEX_A_NAME = 'a_index_things_on_name'
INDEX_B_NAME = 'b_index_things_on_different_columns_in_each_schema'
INDEX_A_COLUMN = 'name'
@@ -30,10 +31,15 @@ class SchemaTest < ActiveRecord::TestCase
set_table_name 'test_schema."things.table"'
end
+ class Thing4 < ActiveRecord::Base
+ set_table_name 'test_schema."Things"'
+ end
+
def setup
@connection = ActiveRecord::Base.connection
@connection.execute "CREATE SCHEMA #{SCHEMA_NAME} CREATE TABLE #{TABLE_NAME} (#{COLUMNS.join(',')})"
@connection.execute "CREATE TABLE #{SCHEMA_NAME}.\"#{TABLE_NAME}.table\" (#{COLUMNS.join(',')})"
+ @connection.execute "CREATE TABLE #{SCHEMA_NAME}.\"#{CAPITALIZED_TABLE_NAME}\" (#{COLUMNS.join(',')})"
@connection.execute "CREATE SCHEMA #{SCHEMA2_NAME} CREATE TABLE #{TABLE_NAME} (#{COLUMNS.join(',')})"
@connection.execute "CREATE INDEX #{INDEX_A_NAME} ON #{SCHEMA_NAME}.#{TABLE_NAME} USING btree (#{INDEX_A_COLUMN});"
@connection.execute "CREATE INDEX #{INDEX_A_NAME} ON #{SCHEMA2_NAME}.#{TABLE_NAME} USING btree (#{INDEX_A_COLUMN});"
@@ -52,6 +58,12 @@ class SchemaTest < ActiveRecord::TestCase
end
end
+ def test_with_schema_prefixed_capitalized_table_name
+ assert_nothing_raised do
+ assert_equal COLUMNS, columns("#{SCHEMA_NAME}.#{CAPITALIZED_TABLE_NAME}")
+ end
+ end
+
def test_with_schema_search_path
assert_nothing_raised do
with_schema_search_path(SCHEMA_NAME) do
@@ -74,21 +86,31 @@ class SchemaTest < ActiveRecord::TestCase
assert_equal 0, Thing1.count
assert_equal 0, Thing2.count
assert_equal 0, Thing3.count
+ assert_equal 0, Thing4.count
Thing1.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now)
assert_equal 1, Thing1.count
assert_equal 0, Thing2.count
assert_equal 0, Thing3.count
+ assert_equal 0, Thing4.count
Thing2.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now)
assert_equal 1, Thing1.count
assert_equal 1, Thing2.count
assert_equal 0, Thing3.count
+ assert_equal 0, Thing4.count
Thing3.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now)
assert_equal 1, Thing1.count
assert_equal 1, Thing2.count
assert_equal 1, Thing3.count
+ assert_equal 0, Thing4.count
+
+ Thing4.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now)
+ assert_equal 1, Thing1.count
+ assert_equal 1, Thing2.count
+ assert_equal 1, Thing3.count
+ assert_equal 1, Thing4.count
end
def test_raise_on_unquoted_schema_name
@@ -113,6 +135,16 @@ class SchemaTest < ActiveRecord::TestCase
do_dump_index_tests_for_schema(SCHEMA2_NAME, INDEX_A_COLUMN, INDEX_B_COLUMN_S2)
end
+ def test_with_uppercase_index_name
+ ActiveRecord::Base.connection.execute "CREATE INDEX \"things_Index\" ON #{SCHEMA_NAME}.things (name)"
+ assert_nothing_raised { ActiveRecord::Base.connection.remove_index :things, :name => "#{SCHEMA_NAME}.things_Index"}
+
+ ActiveRecord::Base.connection.execute "CREATE INDEX \"things_Index\" ON #{SCHEMA_NAME}.things (name)"
+ ActiveRecord::Base.connection.schema_search_path = SCHEMA_NAME
+ assert_nothing_raised { ActiveRecord::Base.connection.remove_index :things, :name => "things_Index"}
+ ActiveRecord::Base.connection.schema_search_path = "public"
+ end
+
private
def columns(table_name)
@connection.send(:column_definitions, table_name).map do |name, type, default|
diff --git a/activerecord/test/models/author.rb b/activerecord/test/models/author.rb
index 4ffac4fe32..0d9ee36b20 100644
--- a/activerecord/test/models/author.rb
+++ b/activerecord/test/models/author.rb
@@ -25,6 +25,8 @@ class Author < ActiveRecord::Base
has_many :comments_with_order_and_conditions, :through => :posts, :source => :comments, :order => 'comments.body', :conditions => "comments.body like 'Thank%'"
has_many :comments_with_include, :through => :posts, :source => :comments, :include => :post
+ has_many :thinking_posts, :class_name => 'Post', :conditions => { :title => 'So I was thinking' }, :dependent => :delete_all
+ has_many :welcome_posts, :class_name => 'Post', :conditions => { :title => 'Welcome to the weblog' }
has_many :comments_desc, :through => :posts, :source => :comments, :order => 'comments.id DESC'
has_many :limited_comments, :through => :posts, :source => :comments, :limit => 1
diff --git a/activerecord/test/models/company.rb b/activerecord/test/models/company.rb
index 02a775f9ef..eb68153bbe 100644
--- a/activerecord/test/models/company.rb
+++ b/activerecord/test/models/company.rb
@@ -78,13 +78,6 @@ class DependentFirm < Company
has_many :companies, :foreign_key => 'client_of', :order => "id", :dependent => :nullify
end
-class ExclusivelyDependentFirm < Company
- has_one :account, :foreign_key => "firm_id", :dependent => :delete
- has_many :dependent_sanitized_conditional_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => :delete_all, :conditions => "name = 'BigShot Inc.'"
- has_many :dependent_conditional_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => :delete_all, :conditions => ["name = ?", 'BigShot Inc.']
- has_many :dependent_hash_conditional_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => :delete_all, :conditions => {:name => 'BigShot Inc.'}
-end
-
class Client < Company
belongs_to :firm, :foreign_key => "client_of"
belongs_to :firm_with_basic_id, :class_name => "Firm", :foreign_key => "firm_id"
@@ -125,6 +118,12 @@ class Client < Company
end
end
+class ExclusivelyDependentFirm < Company
+ has_one :account, :foreign_key => "firm_id", :dependent => :delete
+ has_many :dependent_sanitized_conditional_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => :delete_all, :conditions => "name = 'BigShot Inc.'"
+ has_many :dependent_conditional_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => :delete_all, :conditions => ["name = ?", 'BigShot Inc.']
+ has_many :dependent_hash_conditional_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => :delete_all, :conditions => {:name => 'BigShot Inc.'}
+end
class SpecialClient < Client
end
diff --git a/activerecord/test/models/project.rb b/activerecord/test/models/project.rb
index 550d4ae23c..f25b2ddf77 100644
--- a/activerecord/test/models/project.rb
+++ b/activerecord/test/models/project.rb
@@ -13,7 +13,7 @@ class Project < ActiveRecord::Base
:after_add => Proc.new {|o, r| o.developers_log << "after_adding#{r.id || '<new>'}"},
:before_remove => Proc.new {|o, r| o.developers_log << "before_removing#{r.id}"},
:after_remove => Proc.new {|o, r| o.developers_log << "after_removing#{r.id}"}
- has_and_belongs_to_many :well_payed_salary_groups, :class_name => "Developer", :group => "salary", :having => "SUM(salary) > 10000", :select => "SUM(salary) as salary"
+ has_and_belongs_to_many :well_payed_salary_groups, :class_name => "Developer", :group => "developers.salary", :having => "SUM(salary) > 10000", :select => "SUM(salary) as salary"
attr_accessor :developers_log
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index 5640510c96..98e6d192a5 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -68,6 +68,10 @@ ActiveRecord::Schema.define do
t.boolean :value
end
+ create_table "CamelCase", :force => true do |t|
+ t.string :name
+ end
+
create_table :categories, :force => true do |t|
t.string :name, :null => false
t.string :type
@@ -114,6 +118,8 @@ ActiveRecord::Schema.define do
t.integer :rating, :default => 1
end
+ add_index :companies, [:firm_id, :type, :rating, :ruby_type], :name => "company_index"
+
create_table :computers, :force => true do |t|
t.integer :developer, :null => false
t.integer :extendedWarranty, :null => false