aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorPratik Naik <pratiknaik@gmail.com>2008-09-13 20:25:18 +0100
committerPratik Naik <pratiknaik@gmail.com>2008-09-13 20:25:18 +0100
commitf6c0f688680778a7bf693a69ffee021e1122b01c (patch)
tree09699984d7a4f612689f19e3e0ccb663ae207d3f /activerecord
parent25fd841fe0f1d6f43019595a06aef6d825f5f4d1 (diff)
parent96055414d6197b9705e408c17236f79372a007e5 (diff)
downloadrails-f6c0f688680778a7bf693a69ffee021e1122b01c.tar.gz
rails-f6c0f688680778a7bf693a69ffee021e1122b01c.tar.bz2
rails-f6c0f688680778a7bf693a69ffee021e1122b01c.zip
Merge commit 'mainstream/master'
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/association_preload.rb13
-rwxr-xr-xactiverecord/lib/active_record/associations.rb9
-rwxr-xr-xactiverecord/lib/active_record/base.rb2
-rw-r--r--activerecord/lib/active_record/dirty.rb20
-rw-r--r--activerecord/test/cases/aggregations_test.rb8
-rw-r--r--activerecord/test/cases/associations/belongs_to_associations_test.rb13
-rw-r--r--activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb12
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb5
-rw-r--r--activerecord/test/cases/associations_test.rb12
-rw-r--r--activerecord/test/cases/dirty_test.rb13
-rw-r--r--activerecord/test/cases/finder_test.rb18
-rw-r--r--activerecord/test/cases/inheritance_test.rb2
-rw-r--r--activerecord/test/cases/reflection_test.rb4
-rw-r--r--activerecord/test/cases/sanitize_test.rb25
-rw-r--r--activerecord/test/cases/validations_i18n_test.rb26
-rw-r--r--activerecord/test/cases/validations_test.rb65
-rw-r--r--activerecord/test/models/category.rb3
-rw-r--r--activerecord/test/models/company.rb2
-rw-r--r--activerecord/test/models/parrot.rb1
19 files changed, 209 insertions, 44 deletions
diff --git a/activerecord/lib/active_record/association_preload.rb b/activerecord/lib/active_record/association_preload.rb
index 61fa34ac39..c60850fc77 100644
--- a/activerecord/lib/active_record/association_preload.rb
+++ b/activerecord/lib/active_record/association_preload.rb
@@ -95,7 +95,7 @@ module ActiveRecord
records.each {|record| record.send(reflection.name).loaded}
options = reflection.options
- conditions = "t0.#{reflection.primary_key_name} IN (?)"
+ conditions = "t0.#{reflection.primary_key_name} #{in_or_equals_for_ids(ids)}"
conditions << append_conditions(options, preload_options)
associated_records = reflection.klass.find(:all, :conditions => [conditions, ids],
@@ -222,8 +222,6 @@ module ActiveRecord
table_name = klass.quoted_table_name
primary_key = klass.primary_key
- conditions = "#{table_name}.#{connection.quote_column_name(primary_key)} IN (?)"
- conditions << append_conditions(options, preload_options)
column_type = klass.columns.detect{|c| c.name == primary_key}.type
ids = id_map.keys.uniq.map do |id|
if column_type == :integer
@@ -234,6 +232,8 @@ module ActiveRecord
id
end
end
+ conditions = "#{table_name}.#{connection.quote_column_name(primary_key)} #{in_or_equals_for_ids(ids)}"
+ conditions << append_conditions(options, preload_options)
associated_records = klass.find(:all, :conditions => [conditions, ids],
:include => options[:include],
:select => options[:select],
@@ -248,10 +248,10 @@ module ActiveRecord
table_name = reflection.klass.quoted_table_name
if interface = reflection.options[:as]
- conditions = "#{reflection.klass.quoted_table_name}.#{connection.quote_column_name "#{interface}_id"} IN (?) and #{reflection.klass.quoted_table_name}.#{connection.quote_column_name "#{interface}_type"} = '#{self.base_class.sti_name}'"
+ conditions = "#{reflection.klass.quoted_table_name}.#{connection.quote_column_name "#{interface}_id"} #{in_or_equals_for_ids(ids)} and #{reflection.klass.quoted_table_name}.#{connection.quote_column_name "#{interface}_type"} = '#{self.base_class.sti_name}'"
else
foreign_key = reflection.primary_key_name
- conditions = "#{reflection.klass.quoted_table_name}.#{foreign_key} IN (?)"
+ conditions = "#{reflection.klass.quoted_table_name}.#{foreign_key} #{in_or_equals_for_ids(ids)}"
end
conditions << append_conditions(options, preload_options)
@@ -277,6 +277,9 @@ module ActiveRecord
sql
end
+ def in_or_equals_for_ids(ids)
+ ids.size > 1 ? "IN (?)" : "= ?"
+ end
end
end
end
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index aca2d770fc..5d91315aad 100755
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -1237,7 +1237,7 @@ module ActiveRecord
association = instance_variable_get(ivar) if instance_variable_defined?(ivar)
- if association.nil? || force_reload
+ if association.nil? || !association.loaded? || force_reload
association = association_proxy_class.new(self, reflection)
retval = association.reload
if retval.nil? and association_proxy_class == BelongsToAssociation
@@ -1266,6 +1266,13 @@ module ActiveRecord
end
end
+ if association_proxy_class == BelongsToAssociation
+ define_method("#{reflection.primary_key_name}=") do |target_id|
+ instance_variable_get(ivar).reset if instance_variable_defined?(ivar)
+ write_attribute(reflection.primary_key_name, target_id)
+ end
+ end
+
define_method("set_#{reflection.name}_target") do |target|
return if target.nil? and association_proxy_class == BelongsToAssociation
association = association_proxy_class.new(self, reflection)
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index fc6d762fcd..91b69747e0 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -2152,7 +2152,7 @@ module ActiveRecord #:nodoc:
end
def quote_bound_value(value) #:nodoc:
- if value.respond_to?(:map) && !value.is_a?(String)
+ if value.respond_to?(:map) && !value.acts_like?(:string)
if value.respond_to?(:empty?) && value.empty?
connection.quote(nil)
else
diff --git a/activerecord/lib/active_record/dirty.rb b/activerecord/lib/active_record/dirty.rb
index 7e246e62ca..ae573799ae 100644
--- a/activerecord/lib/active_record/dirty.rb
+++ b/activerecord/lib/active_record/dirty.rb
@@ -34,8 +34,10 @@ module ActiveRecord
# person.name << 'by'
# person.name_change # => ['uncle bob', 'uncle bobby']
module Dirty
+ DIRTY_SUFFIXES = ['_changed?', '_change', '_will_change!', '_was']
+
def self.included(base)
- base.attribute_method_suffix '_changed?', '_change', '_will_change!', '_was'
+ base.attribute_method_suffix *DIRTY_SUFFIXES
base.alias_method_chain :write_attribute, :dirty
base.alias_method_chain :save, :dirty
base.alias_method_chain :save!, :dirty
@@ -44,6 +46,8 @@ module ActiveRecord
base.superclass_delegating_accessor :partial_updates
base.partial_updates = true
+
+ base.send(:extend, ClassMethods)
end
# Do any attributes have unsaved changes?
@@ -161,5 +165,19 @@ module ActiveRecord
old != value
end
+ module ClassMethods
+ def self.extended(base)
+ base.metaclass.alias_method_chain(:alias_attribute, :dirty)
+ end
+
+ def alias_attribute_with_dirty(new_name, old_name)
+ alias_attribute_without_dirty(new_name, old_name)
+ DIRTY_SUFFIXES.each do |suffix|
+ module_eval <<-STR, __FILE__, __LINE__+1
+ def #{new_name}#{suffix}; self.#{old_name}#{suffix}; end
+ STR
+ end
+ end
+ end
end
end
diff --git a/activerecord/test/cases/aggregations_test.rb b/activerecord/test/cases/aggregations_test.rb
index b6656c8631..4e0e1c7f15 100644
--- a/activerecord/test/cases/aggregations_test.rb
+++ b/activerecord/test/cases/aggregations_test.rb
@@ -130,12 +130,16 @@ class DeprecatedAggregationsTest < ActiveRecord::TestCase
end
def test_conversion_block_used_when_converter_option_is_nil
- Person.composed_of(:balance, :class_name => "Money", :mapping => %w(balance amount)) { |balance| balance.to_money }
+ assert_deprecated 'conversion block has been deprecated' do
+ Person.composed_of(:balance, :class_name => "Money", :mapping => %w(balance amount)) { |balance| balance.to_money }
+ end
assert_raise(NoMethodError) { Person.new.balance = 5 }
end
def test_converter_option_overrides_conversion_block
- Person.composed_of(:balance, :class_name => "Money", :mapping => %w(balance amount), :converter => Proc.new { |balance| Money.new(balance) }) { |balance| balance.to_money }
+ assert_deprecated 'conversion block has been deprecated' do
+ Person.composed_of(:balance, :class_name => "Money", :mapping => %w(balance amount), :converter => Proc.new { |balance| Money.new(balance) }) { |balance| balance.to_money }
+ end
person = Person.new
assert_nothing_raised { person.balance = 5 }
diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb
index 9c718c4fef..37b6836a89 100644
--- a/activerecord/test/cases/associations/belongs_to_associations_test.rb
+++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb
@@ -47,6 +47,19 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
assert_equal apple.id, citibank.firm_id
end
+ def test_foreign_key_assignment
+ # Test using an existing record
+ signals37 = accounts(:signals37)
+ assert_equal companies(:first_firm), signals37.firm
+ signals37.firm_id = companies(:another_firm).id
+ assert_equal companies(:another_firm), signals37.firm
+
+ # Test using a new record
+ account = Account.new
+ account.firm_id = companies(:another_firm).id
+ assert_equal companies(:another_firm), account.firm
+ end
+
def test_no_unexpected_aliasing
first_firm = companies(:first_firm)
another_firm = companies(:another_firm)
diff --git a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
index edca3c622b..9981f4c5d5 100644
--- a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
@@ -636,6 +636,18 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
assert_equal 3, Developer.find(:all, :include => {:projects => :developers}, :conditions => 'developers_projects_join.joined_on IS NOT NULL', :group => group.join(",")).size
end
+ def test_find_grouped
+ all_posts_from_category1 = Post.find(:all, :conditions => "category_id = 1", :joins => :categories)
+ grouped_posts_of_category1 = Post.find(:all, :conditions => "category_id = 1", :group => "author_id", :select => 'count(posts.id) as posts_count', :joins => :categories)
+ assert_equal 4, all_posts_from_category1.size
+ assert_equal 1, grouped_posts_of_category1.size
+ end
+
+ def test_find_scoped_grouped
+ assert_equal 4, categories(:general).posts_gruoped_by_title.size
+ assert_equal 1, categories(:technology).posts_gruoped_by_title.size
+ end
+
def test_get_ids
assert_equal projects(:active_record, :action_controller).map(&:id).sort, developers(:david).project_ids.sort
assert_equal [projects(:active_record).id], developers(:jamis).project_ids
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index feac4b002b..5bcbc5eb5b 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -248,6 +248,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_equal 1, grouped_clients_of_firm1.size
end
+ def test_find_scoped_grouped
+ assert_equal 1, companies(:first_firm).clients_grouped_by_firm_id.length
+ assert_equal 2, companies(:first_firm).clients_grouped_by_name.length
+ end
+
def test_adding
force_signal37_to_load_all_clients_of_firm
natural = Client.new("name" => "Natural Company")
diff --git a/activerecord/test/cases/associations_test.rb b/activerecord/test/cases/associations_test.rb
index 056a29438a..2050d16179 100644
--- a/activerecord/test/cases/associations_test.rb
+++ b/activerecord/test/cases/associations_test.rb
@@ -182,6 +182,18 @@ class AssociationProxyTest < ActiveRecord::TestCase
assert_nil p.author.reset
end
+ def test_reset_loads_association_next_time
+ welcome = posts(:welcome)
+ david = authors(:david)
+ author_assoc = welcome.author
+
+ assert_equal david, welcome.author # So we can be sure the test works correctly
+ author_assoc.reset
+ assert !author_assoc.loaded?
+ assert_nil author_assoc.target
+ assert_equal david, welcome.author
+ end
+
def test_reload_returns_assocition
david = developers(:david)
assert_nothing_raised do
diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb
index 4fe1d79f4d..39d38c4e1e 100644
--- a/activerecord/test/cases/dirty_test.rb
+++ b/activerecord/test/cases/dirty_test.rb
@@ -45,6 +45,19 @@ class DirtyTest < ActiveRecord::TestCase
assert_nil pirate.catchphrase_change
end
+ def test_aliased_attribute_changes
+ # the actual attribute here is name, title is an
+ # alias setup via alias_attribute
+ parrot = Parrot.new
+ assert !parrot.title_changed?
+ assert_nil parrot.title_change
+
+ parrot.name = 'Sam'
+ assert parrot.title_changed?
+ assert_nil parrot.title_was
+ assert_equal parrot.name_change, parrot.title_change
+ end
+
def test_nullable_integer_not_marked_as_changed_if_new_value_is_blank
pirate = Pirate.new
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index 1cbc5182d6..cbdff382fe 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -169,6 +169,12 @@ class FinderTest < ActiveRecord::TestCase
assert_equal("fixture_3", developers.first.name)
end
+ def test_find_with_group
+ developers = Developer.find(:all, :group => "salary", :select => "salary")
+ assert_equal 4, developers.size
+ assert_equal 4, developers.map(&:salary).uniq.size
+ end
+
def test_find_with_entire_select_statement
topics = Topic.find_by_sql "SELECT * FROM topics WHERE author_name = 'Mary'"
@@ -297,7 +303,6 @@ class FinderTest < ActiveRecord::TestCase
assert_raises(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => { :author_name => "David", :title => "The First Topic", :replies_count => 1, :approved => true }) }
end
-
def test_condition_interpolation
assert_kind_of Firm, Company.find(:first, :conditions => ["name = '%s'", "37signals"])
assert_nil Company.find(:first, :conditions => ["name = '%s'", "37signals!"])
@@ -392,7 +397,7 @@ class FinderTest < ActiveRecord::TestCase
Company.find(:first, :conditions => ["id=? AND name = ?", 2])
}
assert_raises(ActiveRecord::PreparedStatementInvalid) {
- Company.find(:first, :conditions => ["id=?", 2, 3, 4])
+ Company.find(:first, :conditions => ["id=?", 2, 3, 4])
}
end
@@ -455,6 +460,15 @@ class FinderTest < ActiveRecord::TestCase
assert_equal ActiveRecord::Base.connection.quote(''), bind('?', '')
end
+ def test_bind_chars
+ quoted_bambi = ActiveRecord::Base.connection.quote("Bambi")
+ quoted_bambi_and_thumper = ActiveRecord::Base.connection.quote("Bambi\nand\nThumper")
+ assert_equal "name=#{quoted_bambi}", bind('name=?', "Bambi")
+ assert_equal "name=#{quoted_bambi_and_thumper}", bind('name=?', "Bambi\nand\nThumper")
+ assert_equal "name=#{quoted_bambi}", bind('name=?', "Bambi".chars)
+ assert_equal "name=#{quoted_bambi_and_thumper}", bind('name=?', "Bambi\nand\nThumper".chars)
+ end
+
def test_bind_record
o = Struct.new(:quoted_id).new(1)
assert_equal '1', bind('?', o)
diff --git a/activerecord/test/cases/inheritance_test.rb b/activerecord/test/cases/inheritance_test.rb
index 4fd38bfbc9..a39415618d 100644
--- a/activerecord/test/cases/inheritance_test.rb
+++ b/activerecord/test/cases/inheritance_test.rb
@@ -193,7 +193,7 @@ class InheritanceTest < ActiveRecord::TestCase
def test_eager_load_belongs_to_primary_key_quoting
con = Account.connection
- assert_sql(/\(#{con.quote_table_name('companies')}.#{con.quote_column_name('id')} IN \(1\)\)/) do
+ assert_sql(/\(#{con.quote_table_name('companies')}.#{con.quote_column_name('id')} = 1\)/) do
Account.find(1, :include => :firm)
end
end
diff --git a/activerecord/test/cases/reflection_test.rb b/activerecord/test/cases/reflection_test.rb
index 4b86e32dbf..e339ef41ab 100644
--- a/activerecord/test/cases/reflection_test.rb
+++ b/activerecord/test/cases/reflection_test.rb
@@ -160,8 +160,8 @@ class ReflectionTest < ActiveRecord::TestCase
def test_reflection_of_all_associations
# FIXME these assertions bust a lot
- assert_equal 24, Firm.reflect_on_all_associations.size
- assert_equal 18, Firm.reflect_on_all_associations(:has_many).size
+ assert_equal 26, Firm.reflect_on_all_associations.size
+ assert_equal 20, Firm.reflect_on_all_associations(:has_many).size
assert_equal 6, Firm.reflect_on_all_associations(:has_one).size
assert_equal 0, Firm.reflect_on_all_associations(:belongs_to).size
end
diff --git a/activerecord/test/cases/sanitize_test.rb b/activerecord/test/cases/sanitize_test.rb
new file mode 100644
index 0000000000..0106572ced
--- /dev/null
+++ b/activerecord/test/cases/sanitize_test.rb
@@ -0,0 +1,25 @@
+require "cases/helper"
+require 'models/binary'
+
+class SanitizeTest < ActiveRecord::TestCase
+ def setup
+ end
+
+ def test_sanitize_sql_array_handles_string_interpolation
+ quoted_bambi = ActiveRecord::Base.connection.quote_string("Bambi")
+ assert_equal "name=#{quoted_bambi}", Binary.send(:sanitize_sql_array, ["name=%s", "Bambi"])
+ assert_equal "name=#{quoted_bambi}", Binary.send(:sanitize_sql_array, ["name=%s", "Bambi".chars])
+ quoted_bambi_and_thumper = ActiveRecord::Base.connection.quote_string("Bambi\nand\nThumper")
+ assert_equal "name=#{quoted_bambi_and_thumper}",Binary.send(:sanitize_sql_array, ["name=%s", "Bambi\nand\nThumper"])
+ assert_equal "name=#{quoted_bambi_and_thumper}",Binary.send(:sanitize_sql_array, ["name=%s", "Bambi\nand\nThumper".chars])
+ end
+
+ def test_sanitize_sql_array_handles_bind_variables
+ quoted_bambi = ActiveRecord::Base.connection.quote("Bambi")
+ assert_equal "name=#{quoted_bambi}", Binary.send(:sanitize_sql_array, ["name=?", "Bambi"])
+ assert_equal "name=#{quoted_bambi}", Binary.send(:sanitize_sql_array, ["name=?", "Bambi".chars])
+ quoted_bambi_and_thumper = ActiveRecord::Base.connection.quote("Bambi\nand\nThumper")
+ assert_equal "name=#{quoted_bambi_and_thumper}", Binary.send(:sanitize_sql_array, ["name=?", "Bambi\nand\nThumper"])
+ assert_equal "name=#{quoted_bambi_and_thumper}", Binary.send(:sanitize_sql_array, ["name=?", "Bambi\nand\nThumper".chars])
+ end
+end
diff --git a/activerecord/test/cases/validations_i18n_test.rb b/activerecord/test/cases/validations_i18n_test.rb
index 090f347a20..e34890ef19 100644
--- a/activerecord/test/cases/validations_i18n_test.rb
+++ b/activerecord/test/cases/validations_i18n_test.rb
@@ -40,6 +40,32 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
end
end
+ def test_percent_s_interpolation_syntax_in_error_messages_still_works
+ ActiveSupport::Deprecation.silence do
+ result = I18n.t :does_not_exist, :default => "%s interpolation syntax is deprecated", :value => 'this'
+ assert_equal result, "this interpolation syntax is deprecated"
+ end
+ end
+
+ def test_percent_s_interpolation_syntax_in_error_messages_is_deprecated
+ assert_deprecated('using %s in messages') do
+ I18n.t :does_not_exist, :default => "%s interpolation syntax is deprected", :value => 'this'
+ end
+ end
+
+ def test_percent_d_interpolation_syntax_in_error_messages_still_works
+ ActiveSupport::Deprecation.silence do
+ result = I18n.t :does_not_exist, :default => "%d interpolation syntaxes are deprecated", :count => 2
+ assert_equal result, "2 interpolation syntaxes are deprecated"
+ end
+ end
+
+ def test_percent_d_interpolation_syntax_in_error_messages_is_deprecated
+ assert_deprecated('using %d in messages') do
+ I18n.t :does_not_exist, :default => "%d interpolation syntaxes are deprected", :count => 2
+ end
+ end
+
# ActiveRecord::Errors
uses_mocha 'ActiveRecord::Errors' do
diff --git a/activerecord/test/cases/validations_test.rb b/activerecord/test/cases/validations_test.rb
index 4999d93a86..c049659327 100644
--- a/activerecord/test/cases/validations_test.rb
+++ b/activerecord/test/cases/validations_test.rb
@@ -364,6 +364,13 @@ class ValidationsTest < ActiveRecord::TestCase
assert t2.save, "Should now save t2 as unique"
end
+ def test_validates_uniquness_with_newline_chars
+ Topic.validates_uniqueness_of(:title, :case_sensitive => false)
+
+ t = Topic.new("title" => "new\nline")
+ assert t.save, "Should save t as unique"
+ end
+
def test_validate_uniqueness_with_scope
Reply.validates_uniqueness_of(:content, :scope => "parent_id")
@@ -605,7 +612,7 @@ class ValidationsTest < ActiveRecord::TestCase
end
def test_validate_format_with_formatted_message
- Topic.validates_format_of(:title, :with => /^Valid Title$/, :message => "can't be %s")
+ Topic.validates_format_of(:title, :with => /^Valid Title$/, :message => "can't be {{value}}")
t = Topic.create(:title => 'Invalid title')
assert_equal "can't be Invalid title", t.errors.on(:title)
end
@@ -666,7 +673,7 @@ class ValidationsTest < ActiveRecord::TestCase
end
def test_validates_inclusion_of_with_formatted_message
- Topic.validates_inclusion_of( :title, :in => %w( a b c d e f g ), :message => "option %s is not in the list" )
+ Topic.validates_inclusion_of( :title, :in => %w( a b c d e f g ), :message => "option {{value}} is not in the list" )
assert Topic.create("title" => "a", "content" => "abc").valid?
@@ -691,7 +698,7 @@ class ValidationsTest < ActiveRecord::TestCase
end
def test_validates_exclusion_of_with_formatted_message
- Topic.validates_exclusion_of( :title, :in => %w( abe monkey ), :message => "option %s is restricted" )
+ Topic.validates_exclusion_of( :title, :in => %w( abe monkey ), :message => "option {{value}} is restricted" )
assert Topic.create("title" => "something", "content" => "abc")
@@ -791,7 +798,7 @@ class ValidationsTest < ActiveRecord::TestCase
end
def test_optionally_validates_length_of_using_within_on_create
- Topic.validates_length_of :title, :content, :within => 5..10, :on => :create, :too_long => "my string is too long: %d"
+ Topic.validates_length_of :title, :content, :within => 5..10, :on => :create, :too_long => "my string is too long: {{count}}"
t = Topic.create("title" => "thisisnotvalid", "content" => "whatever")
assert !t.save
@@ -812,7 +819,7 @@ class ValidationsTest < ActiveRecord::TestCase
end
def test_optionally_validates_length_of_using_within_on_update
- Topic.validates_length_of :title, :content, :within => 5..10, :on => :update, :too_short => "my string is too short: %d"
+ Topic.validates_length_of :title, :content, :within => 5..10, :on => :update, :too_short => "my string is too short: {{count}}"
t = Topic.create("title" => "vali", "content" => "whatever")
assert !t.save
@@ -875,7 +882,7 @@ class ValidationsTest < ActiveRecord::TestCase
def test_validates_length_with_globally_modified_error_message
ActiveSupport::Deprecation.silence do
- ActiveRecord::Errors.default_error_messages[:too_short] = 'tu est trops petit hombre %d'
+ ActiveRecord::Errors.default_error_messages[:too_short] = 'tu est trops petit hombre {{count}}'
end
Topic.validates_length_of :title, :minimum => 10
t = Topic.create(:title => 'too short')
@@ -919,7 +926,7 @@ class ValidationsTest < ActiveRecord::TestCase
end
def test_validates_length_of_custom_errors_for_minimum_with_message
- Topic.validates_length_of( :title, :minimum=>5, :message=>"boo %d" )
+ Topic.validates_length_of( :title, :minimum=>5, :message=>"boo {{count}}" )
t = Topic.create("title" => "uhoh", "content" => "whatever")
assert !t.valid?
assert t.errors.on(:title)
@@ -927,7 +934,7 @@ class ValidationsTest < ActiveRecord::TestCase
end
def test_validates_length_of_custom_errors_for_minimum_with_too_short
- Topic.validates_length_of( :title, :minimum=>5, :too_short=>"hoo %d" )
+ Topic.validates_length_of( :title, :minimum=>5, :too_short=>"hoo {{count}}" )
t = Topic.create("title" => "uhoh", "content" => "whatever")
assert !t.valid?
assert t.errors.on(:title)
@@ -935,7 +942,7 @@ class ValidationsTest < ActiveRecord::TestCase
end
def test_validates_length_of_custom_errors_for_maximum_with_message
- Topic.validates_length_of( :title, :maximum=>5, :message=>"boo %d" )
+ Topic.validates_length_of( :title, :maximum=>5, :message=>"boo {{count}}" )
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
assert !t.valid?
assert t.errors.on(:title)
@@ -943,7 +950,7 @@ class ValidationsTest < ActiveRecord::TestCase
end
def test_validates_length_of_custom_errors_for_maximum_with_too_long
- Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d" )
+ Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}" )
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
assert !t.valid?
assert t.errors.on(:title)
@@ -951,7 +958,7 @@ class ValidationsTest < ActiveRecord::TestCase
end
def test_validates_length_of_custom_errors_for_is_with_message
- Topic.validates_length_of( :title, :is=>5, :message=>"boo %d" )
+ Topic.validates_length_of( :title, :is=>5, :message=>"boo {{count}}" )
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
assert !t.valid?
assert t.errors.on(:title)
@@ -959,7 +966,7 @@ class ValidationsTest < ActiveRecord::TestCase
end
def test_validates_length_of_custom_errors_for_is_with_wrong_length
- Topic.validates_length_of( :title, :is=>5, :wrong_length=>"hoo %d" )
+ Topic.validates_length_of( :title, :is=>5, :wrong_length=>"hoo {{count}}" )
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
assert !t.valid?
assert t.errors.on(:title)
@@ -1025,7 +1032,7 @@ class ValidationsTest < ActiveRecord::TestCase
def test_optionally_validates_length_of_using_within_on_create_utf8
with_kcode('UTF8') do
- Topic.validates_length_of :title, :within => 5..10, :on => :create, :too_long => "長すぎます: %d"
+ Topic.validates_length_of :title, :within => 5..10, :on => :create, :too_long => "長すぎます: {{count}}"
t = Topic.create("title" => "一二三四五六七八九十A", "content" => "whatever")
assert !t.save
@@ -1048,7 +1055,7 @@ class ValidationsTest < ActiveRecord::TestCase
def test_optionally_validates_length_of_using_within_on_update_utf8
with_kcode('UTF8') do
- Topic.validates_length_of :title, :within => 5..10, :on => :update, :too_short => "短すぎます: %d"
+ Topic.validates_length_of :title, :within => 5..10, :on => :update, :too_short => "短すぎます: {{count}}"
t = Topic.create("title" => "一二三4", "content" => "whatever")
assert !t.save
@@ -1083,7 +1090,7 @@ class ValidationsTest < ActiveRecord::TestCase
end
def test_validates_length_of_with_block
- Topic.validates_length_of :content, :minimum => 5, :too_short=>"Your essay must be at least %d words.",
+ Topic.validates_length_of :content, :minimum => 5, :too_short=>"Your essay must be at least {{count}} words.",
:tokenizer => lambda {|str| str.scan(/\w+/) }
t = Topic.create!(:content => "this content should be long enough")
assert t.valid?
@@ -1234,7 +1241,7 @@ class ValidationsTest < ActiveRecord::TestCase
def test_if_validation_using_method_true
# When the method returns true
- Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => :condition_is_true )
+ Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :if => :condition_is_true )
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
assert !t.valid?
assert t.errors.on(:title)
@@ -1243,7 +1250,7 @@ class ValidationsTest < ActiveRecord::TestCase
def test_unless_validation_using_method_true
# When the method returns true
- Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :unless => :condition_is_true )
+ Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :unless => :condition_is_true )
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
assert t.valid?
assert !t.errors.on(:title)
@@ -1251,7 +1258,7 @@ class ValidationsTest < ActiveRecord::TestCase
def test_if_validation_using_method_false
# When the method returns false
- Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => :condition_is_true_but_its_not )
+ Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :if => :condition_is_true_but_its_not )
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
assert t.valid?
assert !t.errors.on(:title)
@@ -1259,7 +1266,7 @@ class ValidationsTest < ActiveRecord::TestCase
def test_unless_validation_using_method_false
# When the method returns false
- Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :unless => :condition_is_true_but_its_not )
+ Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :unless => :condition_is_true_but_its_not )
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
assert !t.valid?
assert t.errors.on(:title)
@@ -1268,7 +1275,7 @@ class ValidationsTest < ActiveRecord::TestCase
def test_if_validation_using_string_true
# When the evaluated string returns true
- Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => "a = 1; a == 1" )
+ Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :if => "a = 1; a == 1" )
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
assert !t.valid?
assert t.errors.on(:title)
@@ -1277,7 +1284,7 @@ class ValidationsTest < ActiveRecord::TestCase
def test_unless_validation_using_string_true
# When the evaluated string returns true
- Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :unless => "a = 1; a == 1" )
+ Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :unless => "a = 1; a == 1" )
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
assert t.valid?
assert !t.errors.on(:title)
@@ -1285,7 +1292,7 @@ class ValidationsTest < ActiveRecord::TestCase
def test_if_validation_using_string_false
# When the evaluated string returns false
- Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => "false")
+ Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :if => "false")
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
assert t.valid?
assert !t.errors.on(:title)
@@ -1293,7 +1300,7 @@ class ValidationsTest < ActiveRecord::TestCase
def test_unless_validation_using_string_false
# When the evaluated string returns false
- Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :unless => "false")
+ Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :unless => "false")
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
assert !t.valid?
assert t.errors.on(:title)
@@ -1302,7 +1309,7 @@ class ValidationsTest < ActiveRecord::TestCase
def test_if_validation_using_block_true
# When the block returns true
- Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d",
+ Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}",
:if => Proc.new { |r| r.content.size > 4 } )
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
assert !t.valid?
@@ -1312,7 +1319,7 @@ class ValidationsTest < ActiveRecord::TestCase
def test_unless_validation_using_block_true
# When the block returns true
- Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d",
+ Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}",
:unless => Proc.new { |r| r.content.size > 4 } )
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
assert t.valid?
@@ -1321,7 +1328,7 @@ class ValidationsTest < ActiveRecord::TestCase
def test_if_validation_using_block_false
# When the block returns false
- Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d",
+ Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}",
:if => Proc.new { |r| r.title != "uhohuhoh"} )
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
assert t.valid?
@@ -1330,7 +1337,7 @@ class ValidationsTest < ActiveRecord::TestCase
def test_unless_validation_using_block_false
# When the block returns false
- Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d",
+ Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}",
:unless => Proc.new { |r| r.title != "uhohuhoh"} )
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
assert !t.valid?
@@ -1507,13 +1514,13 @@ class ValidatesNumericalityTest < ActiveRecord::TestCase
end
def test_validates_numericality_with_numeric_message
- Topic.validates_numericality_of :approved, :less_than => 4, :message => "smaller than %d"
+ Topic.validates_numericality_of :approved, :less_than => 4, :message => "smaller than {{count}}"
topic = Topic.new("title" => "numeric test", "approved" => 10)
assert !topic.valid?
assert_equal "smaller than 4", topic.errors.on(:approved)
- Topic.validates_numericality_of :approved, :greater_than => 4, :message => "greater than %d"
+ Topic.validates_numericality_of :approved, :greater_than => 4, :message => "greater than {{count}}"
topic = Topic.new("title" => "numeric test", "approved" => 1)
assert !topic.valid?
diff --git a/activerecord/test/models/category.rb b/activerecord/test/models/category.rb
index 1660c61682..4e9d247a4e 100644
--- a/activerecord/test/models/category.rb
+++ b/activerecord/test/models/category.rb
@@ -13,6 +13,9 @@ class Category < ActiveRecord::Base
has_and_belongs_to_many :post_with_conditions,
:class_name => 'Post',
:conditions => { :title => 'Yet Another Testing Title' }
+
+ has_and_belongs_to_many :posts_gruoped_by_title, :class_name => "Post", :group => "title", :select => "title"
+
def self.what_are_you
'a category...'
end
diff --git a/activerecord/test/models/company.rb b/activerecord/test/models/company.rb
index cd435948a1..0eb8ae0a15 100644
--- a/activerecord/test/models/company.rb
+++ b/activerecord/test/models/company.rb
@@ -55,6 +55,8 @@ class Firm < Company
has_many :readonly_clients, :class_name => 'Client', :readonly => true
has_many :clients_using_primary_key, :class_name => 'Client',
:primary_key => 'name', :foreign_key => 'firm_name'
+ has_many :clients_grouped_by_firm_id, :class_name => "Client", :group => "firm_id", :select => "firm_id"
+ has_many :clients_grouped_by_name, :class_name => "Client", :group => "name", :select => "name"
has_one :account, :foreign_key => "firm_id", :dependent => :destroy, :validate => true
has_one :unvalidated_account, :foreign_key => "firm_id", :class_name => 'Account', :validate => false
diff --git a/activerecord/test/models/parrot.rb b/activerecord/test/models/parrot.rb
index 65191c1aa5..b9431fd1c0 100644
--- a/activerecord/test/models/parrot.rb
+++ b/activerecord/test/models/parrot.rb
@@ -3,6 +3,7 @@ class Parrot < ActiveRecord::Base
has_and_belongs_to_many :pirates
has_and_belongs_to_many :treasures
has_many :loots, :as => :looter
+ alias_attribute :title, :name
end
class LiveParrot < Parrot