aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG5
-rwxr-xr-xactiverecord/lib/active_record/associations.rb19
-rw-r--r--activerecord/lib/active_record/associations/association_collection.rb2
-rw-r--r--activerecord/lib/active_record/associations/association_proxy.rb6
-rw-r--r--activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb6
-rw-r--r--activerecord/lib/active_record/associations/has_many_association.rb6
-rw-r--r--activerecord/lib/active_record/associations/has_many_through_association.rb6
-rwxr-xr-xactiverecord/lib/active_record/associations/has_one_association.rb4
-rwxr-xr-xactiverecord/lib/active_record/base.rb24
-rwxr-xr-xactiverecord/lib/active_record/callbacks.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb7
-rwxr-xr-xactiverecord/lib/active_record/connection_adapters/mysql_adapter.rb11
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb12
-rw-r--r--activerecord/lib/active_record/dirty.rb4
-rw-r--r--activerecord/lib/active_record/reflection.rb4
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb26
-rw-r--r--activerecord/test/cases/dirty_test.rb27
-rw-r--r--activerecord/test/cases/finder_test.rb17
-rw-r--r--activerecord/test/cases/migration_test.rb24
-rw-r--r--activerecord/test/cases/named_scope_test.rb4
-rwxr-xr-xactiverecord/test/models/topic.rb1
21 files changed, 163 insertions, 56 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index 4e05d0fcfd..d6cc589381 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,5 +1,10 @@
*Edge*
+* Allow conditions on multiple tables to be specified using hash. [Pratik Naik]. Example:
+
+ User.all :joins => :items, :conditions => { :age => 10, :items => { :color => 'black' } }
+ Item.first :conditions => { :items => { :color => 'red' } }
+
* Always treat integer :limit as byte length. #420 [Tarmo Tänav]
* Partial updates don't update lock_version if nothing changed. #426 [Daniel Morrison]
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index d2253cb61c..cebc25a42a 100755
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -712,7 +712,8 @@ module ActiveRecord
configure_dependency_for_has_many(reflection)
- add_multiple_associated_save_callbacks(reflection.name) unless options[:validate] == false
+ add_multiple_associated_validation_callbacks(reflection.name) unless options[:validate] == false
+ add_multiple_associated_save_callbacks(reflection.name)
add_association_callbacks(reflection.name, reflection.options)
if options[:through]
@@ -802,7 +803,7 @@ module ActiveRecord
end
after_save method_name
- add_single_associated_save_callbacks(reflection.name) if options[:validate] == true
+ add_single_associated_validation_callbacks(reflection.name) if options[:validate] == true
association_accessor_methods(reflection, HasOneAssociation)
association_constructor_method(:build, reflection, HasOneAssociation)
association_constructor_method(:create, reflection, HasOneAssociation)
@@ -941,7 +942,7 @@ module ActiveRecord
)
end
- add_single_associated_save_callbacks(reflection.name) if options[:validate] == true
+ add_single_associated_validation_callbacks(reflection.name) if options[:validate] == true
configure_dependency_for_belongs_to(reflection)
end
@@ -1044,7 +1045,8 @@ module ActiveRecord
def has_and_belongs_to_many(association_id, options = {}, &extension)
reflection = create_has_and_belongs_to_many_reflection(association_id, options, &extension)
- add_multiple_associated_save_callbacks(reflection.name) unless options[:validate] == false
+ add_multiple_associated_validation_callbacks(reflection.name) unless options[:validate] == false
+ add_multiple_associated_save_callbacks(reflection.name)
collection_accessor_methods(reflection, HasAndBelongsToManyAssociation)
# Don't use a before_destroy callback since users' before_destroy
@@ -1164,7 +1166,7 @@ module ActiveRecord
end
end
- def add_single_associated_save_callbacks(association_name)
+ def add_single_associated_validation_callbacks(association_name)
method_name = "validate_associated_records_for_#{association_name}".to_sym
define_method(method_name) do
association = instance_variable_get("@#{association_name}")
@@ -1176,7 +1178,7 @@ module ActiveRecord
validate method_name
end
- def add_multiple_associated_save_callbacks(association_name)
+ def add_multiple_associated_validation_callbacks(association_name)
method_name = "validate_associated_records_for_#{association_name}".to_sym
ivar = "@#{association_name}"
@@ -1197,6 +1199,10 @@ module ActiveRecord
end
validate method_name
+ end
+
+ def add_multiple_associated_save_callbacks(association_name)
+ ivar = "@#{association_name}"
method_name = "before_save_associated_records_for_#{association_name}".to_sym
define_method(method_name) do
@@ -1218,7 +1224,6 @@ module ActiveRecord
else
[]
end
-
records_to_save.each { |record| association.send(:insert_record, record) } unless records_to_save.blank?
# reconstruct the SQL queries now that we know the owner's id
diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb
index 52d2a9864e..bbd8af7e76 100644
--- a/activerecord/lib/active_record/associations/association_collection.rb
+++ b/activerecord/lib/active_record/associations/association_collection.rb
@@ -187,7 +187,7 @@ module ActiveRecord
if @owner.new_record? || (loaded? && !@reflection.options[:uniq])
@target.size
elsif !loaded? && !@reflection.options[:uniq] && @target.is_a?(Array)
- unsaved_records = Array(@target.detect { |r| r.new_record? })
+ unsaved_records = @target.select { |r| r.new_record? }
unsaved_records.size + count_records
else
count_records
diff --git a/activerecord/lib/active_record/associations/association_proxy.rb b/activerecord/lib/active_record/associations/association_proxy.rb
index 11c64243a2..77fc827e11 100644
--- a/activerecord/lib/active_record/associations/association_proxy.rb
+++ b/activerecord/lib/active_record/associations/association_proxy.rb
@@ -85,7 +85,7 @@ module ActiveRecord
end
def conditions
- @conditions ||= interpolate_sql(sanitize_sql(@reflection.options[:conditions])) if @reflection.options[:conditions]
+ @conditions ||= interpolate_sql(@reflection.sanitized_conditions) if @reflection.sanitized_conditions
end
alias :sql_conditions :conditions
@@ -219,6 +219,10 @@ module ActiveRecord
def flatten_deeper(array)
array.collect { |element| element.respond_to?(:flatten) ? element.flatten : element }.flatten
end
+
+ def owner_quoted_id
+ @owner.quoted_id
+ end
end
end
end
diff --git a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb
index 918404eac6..d516d54151 100644
--- a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb
+++ b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb
@@ -37,7 +37,7 @@ module ActiveRecord
attributes = columns.inject({}) do |attrs, column|
case column.name.to_s
when @reflection.primary_key_name.to_s
- attrs[column.name] = @owner.quoted_id
+ attrs[column.name] = owner_quoted_id
when @reflection.association_foreign_key.to_s
attrs[column.name] = record.quoted_id
else
@@ -64,7 +64,7 @@ module ActiveRecord
records.each { |record| @owner.connection.delete(interpolate_sql(sql, record)) }
else
ids = quoted_record_ids(records)
- sql = "DELETE FROM #{@owner.connection.quote_table_name @reflection.options[:join_table]} WHERE #{@reflection.primary_key_name} = #{@owner.quoted_id} AND #{@reflection.association_foreign_key} IN (#{ids})"
+ sql = "DELETE FROM #{@owner.connection.quote_table_name @reflection.options[:join_table]} WHERE #{@reflection.primary_key_name} = #{owner_quoted_id} AND #{@reflection.association_foreign_key} IN (#{ids})"
@owner.connection.delete(sql)
end
end
@@ -75,7 +75,7 @@ module ActiveRecord
if @reflection.options[:finder_sql]
@finder_sql = @reflection.options[:finder_sql]
else
- @finder_sql = "#{@owner.connection.quote_table_name @reflection.options[:join_table]}.#{@reflection.primary_key_name} = #{@owner.quoted_id} "
+ @finder_sql = "#{@owner.connection.quote_table_name @reflection.options[:join_table]}.#{@reflection.primary_key_name} = #{owner_quoted_id} "
@finder_sql << " AND (#{conditions})" if conditions
end
diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb
index 295beb2966..37440aa84d 100644
--- a/activerecord/lib/active_record/associations/has_many_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_association.rb
@@ -60,7 +60,7 @@ module ActiveRecord
ids = quoted_record_ids(records)
@reflection.klass.update_all(
"#{@reflection.primary_key_name} = NULL",
- "#{@reflection.primary_key_name} = #{@owner.quoted_id} AND #{@reflection.klass.primary_key} IN (#{ids})"
+ "#{@reflection.primary_key_name} = #{owner_quoted_id} AND #{@reflection.klass.primary_key} IN (#{ids})"
)
end
end
@@ -76,12 +76,12 @@ module ActiveRecord
when @reflection.options[:as]
@finder_sql =
- "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_id = #{@owner.quoted_id} AND " +
+ "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_id = #{owner_quoted_id} AND " +
"#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_type = #{@owner.class.quote_value(@owner.class.base_class.name.to_s)}"
@finder_sql << " AND (#{conditions})" if conditions
else
- @finder_sql = "#{@reflection.quoted_table_name}.#{@reflection.primary_key_name} = #{@owner.quoted_id}"
+ @finder_sql = "#{@reflection.quoted_table_name}.#{@reflection.primary_key_name} = #{owner_quoted_id}"
@finder_sql << " AND (#{conditions})" if conditions
end
diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb
index 52ced36d16..e1bfff5923 100644
--- a/activerecord/lib/active_record/associations/has_many_through_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_through_association.rb
@@ -107,12 +107,12 @@ module ActiveRecord
# Associate attributes pointing to owner, quoted.
def construct_quoted_owner_attributes(reflection)
if as = reflection.options[:as]
- { "#{as}_id" => @owner.quoted_id,
+ { "#{as}_id" => owner_quoted_id,
"#{as}_type" => reflection.klass.quote_value(
@owner.class.base_class.name.to_s,
reflection.klass.columns_hash["#{as}_type"]) }
else
- { reflection.primary_key_name => @owner.quoted_id }
+ { reflection.primary_key_name => owner_quoted_id }
end
end
@@ -183,7 +183,7 @@ module ActiveRecord
when @reflection.options[:finder_sql]
@finder_sql = interpolate_sql(@reflection.options[:finder_sql])
- @finder_sql = "#{@reflection.quoted_table_name}.#{@reflection.primary_key_name} = #{@owner.quoted_id}"
+ @finder_sql = "#{@reflection.quoted_table_name}.#{@reflection.primary_key_name} = #{owner_quoted_id}"
@finder_sql << " AND (#{conditions})" if conditions
else
@finder_sql = construct_conditions
diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb
index c2b3503e0d..25a268e95c 100755
--- a/activerecord/lib/active_record/associations/has_one_association.rb
+++ b/activerecord/lib/active_record/associations/has_one_association.rb
@@ -63,10 +63,10 @@ module ActiveRecord
case
when @reflection.options[:as]
@finder_sql =
- "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_id = #{@owner.quoted_id} AND " +
+ "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_id = #{owner_quoted_id} AND " +
"#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_type = #{@owner.class.quote_value(@owner.class.base_class.name.to_s)}"
else
- @finder_sql = "#{@reflection.quoted_table_name}.#{@reflection.primary_key_name} = #{@owner.quoted_id}"
+ @finder_sql = "#{@reflection.quoted_table_name}.#{@reflection.primary_key_name} = #{owner_quoted_id}"
end
@finder_sql << " AND (#{conditions})" if conditions
end
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index c2a8d3ec3d..b0e29ed117 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -1998,24 +1998,28 @@ module ActiveRecord #:nodoc:
# # => "age BETWEEN 13 AND 18"
# { 'other_records.id' => 7 }
# # => "`other_records`.`id` = 7"
+ # { :other_records => { :id => 7 } }
+ # # => "`other_records`.`id` = 7"
# And for value objects on a composed_of relationship:
# { :address => Address.new("123 abc st.", "chicago") }
# # => "address_street='123 abc st.' and address_city='chicago'"
- def sanitize_sql_hash_for_conditions(attrs)
+ def sanitize_sql_hash_for_conditions(attrs, table_name = quoted_table_name)
attrs = expand_hash_conditions_for_aggregates(attrs)
conditions = attrs.map do |attr, value|
- attr = attr.to_s
+ unless value.is_a?(Hash)
+ attr = attr.to_s
+
+ # Extract table name from qualified attribute names.
+ if attr.include?('.')
+ table_name, attr = attr.split('.', 2)
+ table_name = connection.quote_table_name(table_name)
+ end
- # Extract table name from qualified attribute names.
- if attr.include?('.')
- table_name, attr = attr.split('.', 2)
- table_name = connection.quote_table_name(table_name)
+ "#{table_name}.#{connection.quote_column_name(attr)} #{attribute_condition(value)}"
else
- table_name = quoted_table_name
+ sanitize_sql_hash_for_conditions(value, connection.quote_table_name(attr.to_s))
end
-
- "#{table_name}.#{connection.quote_column_name(attr)} #{attribute_condition(value)}"
end.join(' AND ')
replace_bind_variables(conditions, expand_range_bind_variables(attrs.values))
@@ -2069,6 +2073,8 @@ module ActiveRecord #:nodoc:
expanded = []
bind_vars.each do |var|
+ next if var.is_a?(Hash)
+
if var.is_a?(Range)
expanded << var.first
expanded << var.last
diff --git a/activerecord/lib/active_record/callbacks.rb b/activerecord/lib/active_record/callbacks.rb
index 5883cdfbe1..be2621fdb6 100755
--- a/activerecord/lib/active_record/callbacks.rb
+++ b/activerecord/lib/active_record/callbacks.rb
@@ -262,7 +262,7 @@ module ActiveRecord
def valid_with_callbacks? #:nodoc:
return false if callback(:before_validation) == false
if new_record? then result = callback(:before_validation_on_create) else result = callback(:before_validation_on_update) end
- return false if result == false
+ return false if false == result
result = valid_without_callbacks?
@@ -293,7 +293,7 @@ module ActiveRecord
private
def callback(method)
- result = run_callbacks(method) { |result, object| result == false }
+ result = run_callbacks(method) { |result, object| false == result }
if result != false && respond_to_without_attributes?(method)
result = send(method)
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
index f968b9b173..2c03de0f17 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
@@ -30,11 +30,11 @@ module ActiveRecord
end
def text?
- [:string, :text].include? type
+ type == :string || type == :text
end
def number?
- [:float, :integer, :decimal].include? type
+ type == :integer || type == :float || type == :decimal
end
# Returns the Ruby class that corresponds to the abstract data type.
@@ -304,8 +304,7 @@ module ActiveRecord
#
# Available options are (none of these exists by default):
# * <tt>:limit</tt> -
- # Requests a maximum column length (<tt>:string</tt>, <tt>:text</tt>,
- # <tt>:binary</tt> or <tt>:integer</tt> columns only)
+ # Requests a maximum column length. This is number of characters for <tt>:string</tt> and <tt>:text</tt> columns and number of bytes for :binary and :integer columns.
# * <tt>:default</tt> -
# The column's default value. Use nil for NULL.
# * <tt>:null</tt> -
diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
index dd54950790..c5962764f5 100755
--- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -473,11 +473,12 @@ module ActiveRecord
return super unless type.to_s == 'integer'
case limit
- when 1; 'tinyint'
- when 2; 'smallint'
- when 3; 'mediumint'
- when 4, nil; 'int(11)'
- else; 'bigint'
+ when 1; 'tinyint'
+ when 2; 'smallint'
+ when 3; 'mediumint'
+ when nil, 4, 11; 'int(11)' # compatibility with MySQL default
+ when 5..8; 'bigint'
+ else raise(ActiveRecordError, "No integer type has byte size #{limit}")
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 88f703d813..40f34e2dfa 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -48,9 +48,12 @@ module ActiveRecord
private
def extract_limit(sql_type)
- return 8 if sql_type =~ /^bigint/i
- return 2 if sql_type =~ /^smallint/i
- super
+ case sql_type
+ when /^integer/i; 4
+ when /^bigint/i; 8
+ when /^smallint/i; 2
+ else super
+ end
end
# Extracts the scale from PostgreSQL-specific data types.
@@ -795,9 +798,10 @@ module ActiveRecord
when 1..2; 'smallint'
when 3..4, nil; 'integer'
when 5..8; 'bigint'
+ else raise(ActiveRecordError, "No integer type has byte size #{limit}. Use a numeric with precision 0 instead.")
end
end
-
+
# Returns a SELECT DISTINCT clause for a given set of columns and a given ORDER BY clause.
#
# PostgreSQL requires the ORDER BY columns in the select list for distinct queries, and
diff --git a/activerecord/lib/active_record/dirty.rb b/activerecord/lib/active_record/dirty.rb
index 2917f24c20..4ce0356457 100644
--- a/activerecord/lib/active_record/dirty.rb
+++ b/activerecord/lib/active_record/dirty.rb
@@ -142,9 +142,11 @@ module ActiveRecord
def field_changed?(attr, old, value)
if column = column_for_attribute(attr)
- if column.type == :integer && column.null && old.nil?
+ if column.type == :integer && column.null && (old.nil? || old == 0)
# For nullable integer columns, NULL gets stored in database for blank (i.e. '') values.
# Hence we don't record it as a change if the value changes from nil to ''.
+ # If an old value of 0 is set to '' we want this to get changed to nil as otherwise it'll
+ # be typecast back to 0 (''.to_i => 0)
value = nil if value.blank?
else
value = column.type_cast(value)
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index 8614ef8751..3f74c03714 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -112,6 +112,10 @@ module ActiveRecord
name == other_aggregation.name && other_aggregation.options && active_record == other_aggregation.active_record
end
+ def sanitized_conditions #:nodoc:
+ @sanitized_conditions ||= klass.send(:sanitize_sql, options[:conditions]) if options[:conditions]
+ end
+
private
def derive_class_name
name.to_s.camelize
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index b638143c5a..247726bc61 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -345,7 +345,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_invalid_adding_with_validate_false
firm = Firm.find(:first)
client = Client.new
- firm.unvalidated_clients_of_firm << Client.new
+ firm.unvalidated_clients_of_firm << client
assert firm.valid?
assert !client.valid?
@@ -353,6 +353,23 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert client.new_record?
end
+ def test_valid_adding_with_validate_false
+ no_of_clients = Client.count
+
+ firm = Firm.find(:first)
+ client = Client.new("name" => "Apple")
+
+ assert firm.valid?
+ assert client.valid?
+ assert client.new_record?
+
+ firm.unvalidated_clients_of_firm << client
+
+ assert firm.save
+ assert !client.new_record?
+ assert_equal no_of_clients+1, Client.count
+ end
+
def test_build
company = companies(:first_firm)
new_client = assert_no_queries { company.clients_of_firm.build("name" => "Another Client") }
@@ -367,6 +384,13 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_equal 2, company.clients_of_firm(true).size
end
+ def test_collection_size_after_building
+ company = companies(:first_firm) # company already has one client
+ company.clients_of_firm.build("name" => "Another Client")
+ company.clients_of_firm.build("name" => "Yet Another Client")
+ assert_equal 3, company.clients_of_firm.size
+ end
+
def test_build_many
company = companies(:first_firm)
new_clients = assert_no_queries { company.clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) }
diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb
index d70a787208..e5e022050d 100644
--- a/activerecord/test/cases/dirty_test.rb
+++ b/activerecord/test/cases/dirty_test.rb
@@ -55,6 +55,33 @@ class DirtyTest < ActiveRecord::TestCase
end
end
+ def test_zero_to_blank_marked_as_changed
+ pirate = Pirate.new
+ pirate.catchphrase = "Yarrrr, me hearties"
+ pirate.parrot_id = 1
+ pirate.save
+
+ # check the change from 1 to ''
+ pirate = Pirate.find_by_catchphrase("Yarrrr, me hearties")
+ pirate.parrot_id = ''
+ assert pirate.parrot_id_changed?
+ assert_equal([1, nil], pirate.parrot_id_change)
+ pirate.save
+
+ # check the change from nil to 0
+ pirate = Pirate.find_by_catchphrase("Yarrrr, me hearties")
+ pirate.parrot_id = 0
+ assert pirate.parrot_id_changed?
+ assert_equal([nil, 0], pirate.parrot_id_change)
+ pirate.save
+
+ # check the change from 0 to ''
+ pirate = Pirate.find_by_catchphrase("Yarrrr, me hearties")
+ pirate.parrot_id = ''
+ assert pirate.parrot_id_changed?
+ assert_equal([0, nil], pirate.parrot_id_change)
+ end
+
def test_object_should_be_changed_if_any_attribute_is_changed
pirate = Pirate.new
assert !pirate.changed?
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index f48b62ba6b..b97db73b68 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -200,6 +200,23 @@ class FinderTest < ActiveRecord::TestCase
assert_raises(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => { 'topics.approved' => true }) }
end
+ def test_find_on_hash_conditions_with_hashed_table_name
+ assert Topic.find(1, :conditions => {:topics => { :approved => false }})
+ assert_raises(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => {:topics => { :approved => true }}) }
+ end
+
+ def test_find_with_hash_conditions_on_joined_table
+ firms = Firm.all :joins => :account, :conditions => {:accounts => { :credit_limit => 50 }}
+ assert_equal 1, firms.size
+ assert_equal companies(:first_firm), firms.first
+ end
+
+ def test_find_with_hash_conditions_on_joined_table_and_with_range
+ firms = DependentFirm.all :joins => :account, :conditions => {:name => 'RailsCore', :accounts => { :credit_limit => 55..60 }}
+ assert_equal 1, firms.size
+ assert_equal companies(:rails_core), firms.first
+ end
+
def test_find_on_hash_conditions_with_explicit_table_name_and_aggregate
david = customers(:david)
assert Customer.find(david.id, :conditions => { 'customers.name' => david.name, :address => david.address })
diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb
index 908951590c..4482b487dd 100644
--- a/activerecord/test/cases/migration_test.rb
+++ b/activerecord/test/cases/migration_test.rb
@@ -153,9 +153,10 @@ if ActiveRecord::Base.connection.supports_migrations?
t.column :default_int, :integer
- t.column :one_int, :integer, :limit => 1
- t.column :four_int, :integer, :limit => 4
- t.column :eight_int, :integer, :limit => 8
+ t.column :one_int, :integer, :limit => 1
+ t.column :four_int, :integer, :limit => 4
+ t.column :eight_int, :integer, :limit => 8
+ t.column :eleven_int, :integer, :limit => 11
end
end
@@ -167,17 +168,20 @@ if ActiveRecord::Base.connection.supports_migrations?
one = columns.detect { |c| c.name == "one_int" }
four = columns.detect { |c| c.name == "four_int" }
eight = columns.detect { |c| c.name == "eight_int" }
+ eleven = columns.detect { |c| c.name == "eleven_int" }
if current_adapter?(:PostgreSQLAdapter)
assert_equal 'integer', default.sql_type
assert_equal 'smallint', one.sql_type
assert_equal 'integer', four.sql_type
assert_equal 'bigint', eight.sql_type
+ assert_equal 'integer', eleven.sql_type
elsif current_adapter?(:MysqlAdapter)
- assert_match /^int\(\d+\)/, default.sql_type
- assert_match /^tinyint\(\d+\)/, one.sql_type
- assert_match /^int\(\d+\)/, four.sql_type
- assert_match /^bigint\(\d+\)/, eight.sql_type
+ assert_match 'int(11)', default.sql_type
+ assert_match 'tinyint', one.sql_type
+ assert_match 'int', four.sql_type
+ assert_match 'bigint', eight.sql_type
+ assert_match 'int(11)', eleven.sql_type
elsif current_adapter?(:OracleAdapter)
assert_equal 'NUMBER(38)', default.sql_type
assert_equal 'NUMBER(1)', one.sql_type
@@ -1242,10 +1246,10 @@ if ActiveRecord::Base.connection.supports_migrations?
end
def integer_column
- if current_adapter?(:SQLite3Adapter) || current_adapter?(:SQLiteAdapter) || current_adapter?(:PostgreSQLAdapter)
- "integer"
- else
+ if current_adapter?(:MysqlAdapter)
'int(11)'
+ else
+ 'integer'
end
end
diff --git a/activerecord/test/cases/named_scope_test.rb b/activerecord/test/cases/named_scope_test.rb
index 393ba086c9..7d73541ee1 100644
--- a/activerecord/test/cases/named_scope_test.rb
+++ b/activerecord/test/cases/named_scope_test.rb
@@ -65,6 +65,10 @@ class NamedScopeTest < ActiveRecord::TestCase
assert_equal Topic.replied.approved, Topic.replied.approved_as_string
end
+ def test_scopes_can_be_specified_with_deep_hash_conditions
+ assert_equal Topic.replied.approved, Topic.replied.approved_as_hash_condition
+ end
+
def test_scopes_are_composable
assert_equal (approved = Topic.find(:all, :conditions => {:approved => true})), Topic.approved
assert_equal (replied = Topic.find(:all, :conditions => 'replies_count > 0')), Topic.replied
diff --git a/activerecord/test/models/topic.rb b/activerecord/test/models/topic.rb
index 423b6fe52b..47b2eec938 100755
--- a/activerecord/test/models/topic.rb
+++ b/activerecord/test/models/topic.rb
@@ -4,6 +4,7 @@ class Topic < ActiveRecord::Base
{ :conditions => ['written_on < ?', time] }
}
named_scope :approved, :conditions => {:approved => true}
+ named_scope :approved_as_hash_condition, :conditions => {:topics => {:approved => true}}
named_scope 'approved_as_string', :conditions => {:approved => true}
named_scope :replied, :conditions => ['replies_count > 0']
named_scope :anonymous_extension do