From 5bbca48c227044a05e5c685249801d4230d7dd08 Mon Sep 17 00:00:00 2001 From: Jamis Buck Date: Wed, 10 Sep 2008 13:32:10 -0600 Subject: Fix Sri Jayawardenepura time zone to map to Asia/Colombo --- activesupport/CHANGELOG | 2 ++ activesupport/lib/active_support/values/time_zone.rb | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index b38a5061d5..7d7a6920e2 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -1,5 +1,7 @@ *Edge* +* Fixed Sri Jayawardenepura time zone to map to Asia/Colombo [Jamis Buck] + * Added Inflector#parameterize for easy slug generation ("Donald E. Knuth".parameterize => "donald-e-knuth") #713 [Matt Darby] * Changed cache benchmarking to be reported in milliseconds [DHH] diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb index 788d40bfa8..a294dd0ba3 100644 --- a/activesupport/lib/active_support/values/time_zone.rb +++ b/activesupport/lib/active_support/values/time_zone.rb @@ -124,7 +124,7 @@ module ActiveSupport "Kathmandu" => "Asia/Katmandu", "Astana" => "Asia/Dhaka", "Dhaka" => "Asia/Dhaka", - "Sri Jayawardenepura" => "Asia/Dhaka", + "Sri Jayawardenepura" => "Asia/Colombo", "Almaty" => "Asia/Almaty", "Novosibirsk" => "Asia/Novosibirsk", "Rangoon" => "Asia/Rangoon", -- cgit v1.2.3 From 6ce13429cbc1359d85e1dc99c84561840e89d455 Mon Sep 17 00:00:00 2001 From: rsl Date: Wed, 10 Sep 2008 14:22:05 -0400 Subject: fixed association preloading to use = instead of IN when there's only one record [#1013 state:committed] Signed-off-by: Jeremy Kemper --- activerecord/lib/active_record/association_preload.rb | 13 ++++++++----- activerecord/test/cases/inheritance_test.rb | 2 +- 2 files changed, 9 insertions(+), 6 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/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 -- cgit v1.2.3 From 2ba9ca95f99c14cd95e90b7bb172ebb29ab25a72 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Wed, 10 Sep 2008 18:56:03 -0500 Subject: Removed monitor from MemoryStore and created a seperate threadsafe store called SynchronizedMemoryStore --- .../lib/active_support/cache/memory_store.rb | 50 +++++----------------- .../cache/synchronized_memory_store.rb | 46 ++++++++++++++++++++ 2 files changed, 57 insertions(+), 39 deletions(-) create mode 100644 activesupport/lib/active_support/cache/synchronized_memory_store.rb diff --git a/activesupport/lib/active_support/cache/memory_store.rb b/activesupport/lib/active_support/cache/memory_store.rb index f3e4b8c13b..c1a713b4c5 100644 --- a/activesupport/lib/active_support/cache/memory_store.rb +++ b/activesupport/lib/active_support/cache/memory_store.rb @@ -3,63 +3,35 @@ module ActiveSupport class MemoryStore < Store def initialize @data = {} - @guard = Monitor.new - end - - def fetch(key, options = {}) - @guard.synchronize do - super - end end def read(name, options = nil) - @guard.synchronize do - super - @data[name] - end + super + @data[name] end def write(name, value, options = nil) - @guard.synchronize do - super - @data[name] = value.freeze - end + super + @data[name] = value.freeze end def delete(name, options = nil) - @guard.synchronize do - @data.delete(name) - end + super + @data.delete(name) end def delete_matched(matcher, options = nil) - @guard.synchronize do - @data.delete_if { |k,v| k =~ matcher } - end + super + @data.delete_if { |k,v| k =~ matcher } end def exist?(name,options = nil) - @guard.synchronize do - @data.has_key?(name) - end - end - - def increment(key, amount = 1) - @guard.synchronize do - super - end - end - - def decrement(key, amount = 1) - @guard.synchronize do - super - end + super + @data.has_key?(name) end def clear - @guard.synchronize do - @data.clear - end + @data.clear end end end diff --git a/activesupport/lib/active_support/cache/synchronized_memory_store.rb b/activesupport/lib/active_support/cache/synchronized_memory_store.rb new file mode 100644 index 0000000000..d2ff28768f --- /dev/null +++ b/activesupport/lib/active_support/cache/synchronized_memory_store.rb @@ -0,0 +1,46 @@ +module ActiveSupport + module Cache + class SynchronizedMemoryStore < MemoryStore + def initialize + super + @guard = Monitor.new + end + + def fetch(key, options = {}) + @guard.synchronize { super } + end + + def read(name, options = nil) + @guard.synchronize { super } + end + + def write(name, value, options = nil) + @guard.synchronize { super } + end + + def delete(name, options = nil) + @guard.synchronize { super } + end + + def delete_matched(matcher, options = nil) + @guard.synchronize { super } + end + + def exist?(name,options = nil) + @guard.synchronize { super } + end + + def increment(key, amount = 1) + @guard.synchronize { super } + end + + def decrement(key, amount = 1) + @guard.synchronize { super } + end + + def clear + @guard.synchronize { super } + end + end + end +end -- cgit v1.2.3 From 70a4f6c2dd66d855ff66a176076ad45caf3ed6ab Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Wed, 10 Sep 2008 19:05:53 -0500 Subject: Switched computed public paths cache over to a simple hash w/ mutex --- .../lib/action_view/helpers/asset_tag_helper.rb | 32 ++++++++++++---------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index ed33f082b9..a926599e25 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -463,7 +463,8 @@ module ActionView end private - COMPUTED_PUBLIC_PATHS = ActiveSupport::Cache::MemoryStore.new.silence! + COMPUTED_PUBLIC_PATHS = {} + COMPUTED_PUBLIC_PATHS_GUARD = Mutex.new # Add the the extension +ext+ if not present. Return full URLs otherwise untouched. # Prefix with /dir/ if lacking a leading +/+. Account for relative URL @@ -483,23 +484,24 @@ module ActionView dir, source, ext, include_host ].join end - source = COMPUTED_PUBLIC_PATHS.fetch(cache_key) do - begin - source += ".#{ext}" if ext && File.extname(source).blank? || File.exist?(File.join(ASSETS_DIR, dir, "#{source}.#{ext}")) - - if source =~ %r{^[-a-z]+://} - source - else - source = "/#{dir}/#{source}" unless source[0] == ?/ - if has_request - unless source =~ %r{^#{ActionController::Base.relative_url_root}/} - source = "#{ActionController::Base.relative_url_root}#{source}" + COMPUTED_PUBLIC_PATHS_GUARD.synchronize do + source = COMPUTED_PUBLIC_PATHS[cache_key] ||= + begin + source += ".#{ext}" if ext && File.extname(source).blank? || File.exist?(File.join(ASSETS_DIR, dir, "#{source}.#{ext}")) + + if source =~ %r{^[-a-z]+://} + source + else + source = "/#{dir}/#{source}" unless source[0] == ?/ + if has_request + unless source =~ %r{^#{ActionController::Base.relative_url_root}/} + source = "#{ActionController::Base.relative_url_root}#{source}" + end end - end - rewrite_asset_path(source) + rewrite_asset_path(source) + end end - end end if include_host && source !~ %r{^[-a-z]+://} -- cgit v1.2.3 From 79c8b104d676ce40268caaa530b7e4dcc0a8ff20 Mon Sep 17 00:00:00 2001 From: Sven Fuchs Date: Thu, 11 Sep 2008 00:30:07 +0200 Subject: change activerecord validation tests to not use the deprecated interpolation syntax any more Signed-off-by: Jeremy Kemper --- activerecord/test/cases/validations_test.rb | 58 ++++++++++++++--------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/activerecord/test/cases/validations_test.rb b/activerecord/test/cases/validations_test.rb index 4999d93a86..1f5f9fd489 100644 --- a/activerecord/test/cases/validations_test.rb +++ b/activerecord/test/cases/validations_test.rb @@ -605,7 +605,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 +666,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 +691,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 +791,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 +812,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 +875,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 +919,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 +927,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 +935,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 +943,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 +951,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 +959,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 +1025,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 +1048,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 +1083,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 +1234,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 +1243,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 +1251,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 +1259,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 +1268,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 +1277,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 +1285,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 +1293,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 +1302,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 +1312,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 +1321,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 +1330,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 +1507,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? -- cgit v1.2.3 From 31dcd7811185134f16a52744ad50f87d197ca438 Mon Sep 17 00:00:00 2001 From: Sven Fuchs Date: Thu, 11 Sep 2008 00:35:58 +0200 Subject: add activerecord tests for deprecation of %s and %d in error messages (and translations in general) Signed-off-by: Jeremy Kemper --- activerecord/test/cases/validations_i18n_test.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/activerecord/test/cases/validations_i18n_test.rb b/activerecord/test/cases/validations_i18n_test.rb index 090f347a20..4d23321ede 100644 --- a/activerecord/test/cases/validations_i18n_test.rb +++ b/activerecord/test/cases/validations_i18n_test.rb @@ -40,6 +40,18 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase 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_is_deprecated + assert_deprecated('using %d in messages') do + I18n.t :does_not_exist, :default => "%d interpolation syntax is deprected", :count => 1 + end + end + # ActiveRecord::Errors uses_mocha 'ActiveRecord::Errors' do -- cgit v1.2.3 From e826c992014b24475203bf1a88b3f7a2356f7ff5 Mon Sep 17 00:00:00 2001 From: Sven Fuchs Date: Thu, 11 Sep 2008 00:39:56 +0200 Subject: add activerecord tests to make sure the deprecated %s and %d interpolation syntax still works [#1016 state:committed] Signed-off-by: Jeremy Kemper --- activerecord/test/cases/validations_i18n_test.rb | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/activerecord/test/cases/validations_i18n_test.rb b/activerecord/test/cases/validations_i18n_test.rb index 4d23321ede..e34890ef19 100644 --- a/activerecord/test/cases/validations_i18n_test.rb +++ b/activerecord/test/cases/validations_i18n_test.rb @@ -40,15 +40,29 @@ 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 syntax is deprected", :count => 1 + I18n.t :does_not_exist, :default => "%d interpolation syntaxes are deprected", :count => 2 end end -- cgit v1.2.3 From 9460d45988981005b5e91d3db2d3334b01bba3a8 Mon Sep 17 00:00:00 2001 From: Michael Koziarski Date: Thu, 11 Sep 2008 11:21:22 +0200 Subject: Add missing assert_deprecated calls to prevent spam during test runs --- activerecord/test/cases/aggregations_test.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) 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 } -- cgit v1.2.3 From 46bac29de7e39bd2af6ed6cfba0498a921b5213e Mon Sep 17 00:00:00 2001 From: Jamis Buck Date: Thu, 11 Sep 2008 08:33:39 -0600 Subject: Add the Asia/Colombo definition from the tzinfo gem --- .../tzinfo/definitions/Asia/Colombo.rb | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Colombo.rb diff --git a/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Colombo.rb b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Colombo.rb new file mode 100644 index 0000000000..f6531fa819 --- /dev/null +++ b/activesupport/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/definitions/Asia/Colombo.rb @@ -0,0 +1,30 @@ +require 'tzinfo/timezone_definition' + +module TZInfo + module Definitions + module Asia + module Colombo + include TimezoneDefinition + + timezone 'Asia/Colombo' do |tz| + tz.offset :o0, 19164, 0, :LMT + tz.offset :o1, 19172, 0, :MMT + tz.offset :o2, 19800, 0, :IST + tz.offset :o3, 19800, 1800, :IHST + tz.offset :o4, 19800, 3600, :IST + tz.offset :o5, 23400, 0, :LKT + tz.offset :o6, 21600, 0, :LKT + + tz.transition 1879, 12, :o1, 17335550003, 7200 + tz.transition 1905, 12, :o2, 52211763607, 21600 + tz.transition 1942, 1, :o3, 116657485, 48 + tz.transition 1942, 8, :o4, 9722413, 4 + tz.transition 1945, 10, :o2, 38907909, 16 + tz.transition 1996, 5, :o5, 832962600 + tz.transition 1996, 10, :o6, 846266400 + tz.transition 2006, 4, :o2, 1145039400 + end + end + end + end +end -- cgit v1.2.3 From 1ddde91303883b47f2215779cf45d7008377bd0d Mon Sep 17 00:00:00 2001 From: Michael Koziarski Date: Thu, 11 Sep 2008 16:03:38 +0200 Subject: Flesh out the parameterize method to support non-ascii text and underscores. --- activesupport/lib/active_support/inflector.rb | 2 +- activesupport/test/inflector_test_cases.rb | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/activesupport/lib/active_support/inflector.rb b/activesupport/lib/active_support/inflector.rb index e5f0063285..8a917a9eb2 100644 --- a/activesupport/lib/active_support/inflector.rb +++ b/activesupport/lib/active_support/inflector.rb @@ -257,7 +257,7 @@ module ActiveSupport # <%= link_to(@person.name, person_path %> # # => Donald E. Knuth def parameterize(string, sep = '-') - string.gsub(/[^a-z0-9]+/i, sep).downcase + string.chars.normalize(:kd).to_s.gsub(/[^\x00-\x7F]+/, '').gsub(/[^a-z0-9_\-]+/i, sep).downcase end # Create the name of a table like Rails does for models to table names. This method diff --git a/activesupport/test/inflector_test_cases.rb b/activesupport/test/inflector_test_cases.rb index d399c90385..8057809dbd 100644 --- a/activesupport/test/inflector_test_cases.rb +++ b/activesupport/test/inflector_test_cases.rb @@ -144,7 +144,10 @@ module InflectorTestCases StringToParameterized = { "Donald E. Knuth" => "donald-e-knuth", - "Random text with *(bad)* characters" => "random-text-with-bad-characters" + "Random text with *(bad)* characters" => "random-text-with-bad-characters", + "Malmö" => "malmo", + "Garçons" => "garcons", + "Allow_Under_Scores" => "allow_under_scores" } UnderscoreToHuman = { -- cgit v1.2.3 From c98cb8ffc2f42bff565994951af9412e52fcdc58 Mon Sep 17 00:00:00 2001 From: miloops Date: Thu, 11 Sep 2008 12:06:36 -0300 Subject: Add --debugger option to script/console. Signed-off-by: Michael Koziarski [#1025 state:committed] --- railties/lib/commands/console.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/railties/lib/commands/console.rb b/railties/lib/commands/console.rb index 2b9d92f647..63df834639 100644 --- a/railties/lib/commands/console.rb +++ b/railties/lib/commands/console.rb @@ -1,11 +1,13 @@ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb' require 'optparse' + options = { :sandbox => false, :irb => irb } OptionParser.new do |opt| opt.banner = "Usage: console [environment] [options]" opt.on('-s', '--sandbox', 'Rollback database modifications on exit.') { |v| options[:sandbox] = v } opt.on("--irb=[#{irb}]", 'Invoke a different irb.') { |v| options[:irb] = v } + opt.on("--debugger", 'Enable ruby-debugging for the console.') { |v| options[:debugger] = v } opt.parse!(ARGV) end @@ -15,6 +17,17 @@ libs << " -r console_app" libs << " -r console_sandbox" if options[:sandbox] libs << " -r console_with_helpers" +if options[:debugger] + begin + require 'ruby-debug' + libs << " -r ruby-debug" + puts "=> Debugger enabled" + rescue Exception + puts "You need to install ruby-debug to run the console in debugging mode. With gems, use 'gem install ruby-debug'" + exit + end +end + ENV['RAILS_ENV'] = case ARGV.first when "p"; "production" when "d"; "development" -- cgit v1.2.3 From 923f4ecad202e45ef117d592053c8b86549eb9d7 Mon Sep 17 00:00:00 2001 From: wmoxam Date: Thu, 11 Sep 2008 11:33:15 -0400 Subject: Fixes validates_uniquness_of problem with case insensitive string containing newline characters Signed-off-by: Michael Koziarski --- activerecord/lib/active_record/validations.rb | 2 +- activerecord/test/cases/validations_test.rb | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb index 577e30ec86..ac7a87d59f 100644 --- a/activerecord/lib/active_record/validations.rb +++ b/activerecord/lib/active_record/validations.rb @@ -665,7 +665,7 @@ module ActiveRecord condition_params = [value] else condition_sql = "LOWER(#{sql_attribute}) #{comparison_operator}" - condition_params = [value.chars.downcase] + condition_params = [value.chars.downcase.to_s] end if scope = configuration[:scope] diff --git a/activerecord/test/cases/validations_test.rb b/activerecord/test/cases/validations_test.rb index 1f5f9fd489..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") -- cgit v1.2.3 From babbc1580da9e4a23921ab68d47c7c0d2e8447da Mon Sep 17 00:00:00 2001 From: Manfred Stienstra Date: Thu, 11 Sep 2008 22:38:20 +0200 Subject: Fix ActiveRecord::Base.quote_bound_value for ActiveSupper::Multibyte::Chars values. - Adds String#acts_like_string? - Adds Chars#acts_like_string? Signed-off-by: Michael Koziarski [#1029 state:committed] --- activerecord/lib/active_record/base.rb | 2 +- activerecord/test/cases/finder_test.rb | 12 +++++++++-- activerecord/test/cases/sanitize_test.rb | 25 ++++++++++++++++++++++ .../lib/active_support/core_ext/string.rb | 2 ++ .../lib/active_support/core_ext/string/behavior.rb | 13 +++++++++++ .../lib/active_support/multibyte/chars.rb | 5 +++++ activesupport/test/core_ext/string_ext_test.rb | 6 ++++++ activesupport/test/multibyte_chars_test.rb | 4 ++++ 8 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 activerecord/test/cases/sanitize_test.rb create mode 100644 activesupport/lib/active_support/core_ext/string/behavior.rb 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/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index 1cbc5182d6..aede8a6393 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -297,7 +297,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 +391,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 +454,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/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/activesupport/lib/active_support/core_ext/string.rb b/activesupport/lib/active_support/core_ext/string.rb index 25386af70a..7ff2f11eff 100644 --- a/activesupport/lib/active_support/core_ext/string.rb +++ b/activesupport/lib/active_support/core_ext/string.rb @@ -6,6 +6,7 @@ require 'active_support/core_ext/string/iterators' require 'active_support/core_ext/string/unicode' require 'active_support/core_ext/string/xchar' require 'active_support/core_ext/string/filters' +require 'active_support/core_ext/string/behavior' class String #:nodoc: include ActiveSupport::CoreExtensions::String::Access @@ -15,4 +16,5 @@ class String #:nodoc: include ActiveSupport::CoreExtensions::String::StartsEndsWith include ActiveSupport::CoreExtensions::String::Iterators include ActiveSupport::CoreExtensions::String::Unicode + include ActiveSupport::CoreExtensions::String::Behavior end diff --git a/activesupport/lib/active_support/core_ext/string/behavior.rb b/activesupport/lib/active_support/core_ext/string/behavior.rb new file mode 100644 index 0000000000..a93ca3027f --- /dev/null +++ b/activesupport/lib/active_support/core_ext/string/behavior.rb @@ -0,0 +1,13 @@ +module ActiveSupport #:nodoc: + module CoreExtensions #:nodoc: + module String #:nodoc: + module Behavior + # Enable more predictable duck-typing on String-like classes. See + # Object#acts_like?. + def acts_like_string? + true + end + end + end + end +end \ No newline at end of file diff --git a/activesupport/lib/active_support/multibyte/chars.rb b/activesupport/lib/active_support/multibyte/chars.rb index 185d03020c..de2c83f8d1 100644 --- a/activesupport/lib/active_support/multibyte/chars.rb +++ b/activesupport/lib/active_support/multibyte/chars.rb @@ -49,6 +49,11 @@ module ActiveSupport::Multibyte #:nodoc: false end + # Enable more predictable duck-typing on String-like classes. See Object#acts_like?. + def acts_like_string? + true + end + # Create a new Chars instance. def initialize(str) @string = str.respond_to?(:string) ? str.string : str diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb index c9f959ef32..c0decf2c3f 100644 --- a/activesupport/test/core_ext/string_ext_test.rb +++ b/activesupport/test/core_ext/string_ext_test.rb @@ -201,3 +201,9 @@ class StringInflectionsTest < Test::Unit::TestCase end end end + +class StringBehaviourTest < Test::Unit::TestCase + def test_acts_like_string + assert 'Bambi'.acts_like_string? + end +end \ No newline at end of file diff --git a/activesupport/test/multibyte_chars_test.rb b/activesupport/test/multibyte_chars_test.rb index 63cfadb7ec..a87309b038 100644 --- a/activesupport/test/multibyte_chars_test.rb +++ b/activesupport/test/multibyte_chars_test.rb @@ -167,6 +167,10 @@ class CharsTest < Test::Unit::TestCase assert_equal false, 'test'.chars.respond_to?(:a_method_that_doesnt_exist) end + def test_acts_like_string + assert 'Bambi'.chars.acts_like_string? + end + protected def with_kcode(kcode) -- cgit v1.2.3 From 095ad690f3fb6df4e89446dd40e03cf2c204e42a Mon Sep 17 00:00:00 2001 From: Michael Koziarski Date: Thu, 11 Sep 2008 22:47:45 +0200 Subject: Remove the .to_s fix in validates_uniqueness_of, as Chars get quoted correctly. --- activerecord/lib/active_record/validations.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb index ac7a87d59f..577e30ec86 100644 --- a/activerecord/lib/active_record/validations.rb +++ b/activerecord/lib/active_record/validations.rb @@ -665,7 +665,7 @@ module ActiveRecord condition_params = [value] else condition_sql = "LOWER(#{sql_attribute}) #{comparison_operator}" - condition_params = [value.chars.downcase.to_s] + condition_params = [value.chars.downcase] end if scope = configuration[:scope] -- cgit v1.2.3 From a37c5ae961366e3d693991b51d0830d40ae37e08 Mon Sep 17 00:00:00 2001 From: miloops Date: Thu, 11 Sep 2008 17:41:55 -0300 Subject: Improve test coverage when using the group option in find, has_many or has_and_belongs_to_many. Signed-off-by: Michael Koziarski --- .../has_and_belongs_to_many_associations_test.rb | 12 ++++++++++++ .../test/cases/associations/has_many_associations_test.rb | 5 +++++ activerecord/test/cases/finder_test.rb | 6 ++++++ activerecord/test/cases/reflection_test.rb | 4 ++-- activerecord/test/models/category.rb | 3 +++ activerecord/test/models/company.rb | 2 ++ 6 files changed, 30 insertions(+), 2 deletions(-) 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/finder_test.rb b/activerecord/test/cases/finder_test.rb index aede8a6393..ddfebaec08 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") + assert_equal 4, developers.size + assert_equal 4, developers.uniq(&:salary).size + end + def test_find_with_entire_select_statement topics = Topic.find_by_sql "SELECT * FROM topics WHERE author_name = 'Mary'" diff --git a/activerecord/test/cases/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/models/category.rb b/activerecord/test/models/category.rb index 1660c61682..a06dd78011 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" + def self.what_are_you 'a category...' end diff --git a/activerecord/test/models/company.rb b/activerecord/test/models/company.rb index cd435948a1..1abf3f3918 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" + has_many :clients_grouped_by_name, :class_name => "Client", :group => "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 -- cgit v1.2.3 From 646b5bfa61f8e803d98bd1557c53ea961cc6b16d Mon Sep 17 00:00:00 2001 From: miloops Date: Thu, 11 Sep 2008 19:14:06 -0300 Subject: Use select and change test so new tests can work on postgres. Signed-off-by: Michael Koziarski --- activerecord/test/cases/finder_test.rb | 4 ++-- activerecord/test/models/category.rb | 2 +- activerecord/test/models/company.rb | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index ddfebaec08..cbdff382fe 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -170,9 +170,9 @@ class FinderTest < ActiveRecord::TestCase end def test_find_with_group - developers = Developer.find(:all, :group => "salary") + developers = Developer.find(:all, :group => "salary", :select => "salary") assert_equal 4, developers.size - assert_equal 4, developers.uniq(&:salary).size + assert_equal 4, developers.map(&:salary).uniq.size end def test_find_with_entire_select_statement diff --git a/activerecord/test/models/category.rb b/activerecord/test/models/category.rb index a06dd78011..4e9d247a4e 100644 --- a/activerecord/test/models/category.rb +++ b/activerecord/test/models/category.rb @@ -14,7 +14,7 @@ class Category < ActiveRecord::Base :class_name => 'Post', :conditions => { :title => 'Yet Another Testing Title' } - has_and_belongs_to_many :posts_gruoped_by_title, :class_name => "Post", :group => "title" + has_and_belongs_to_many :posts_gruoped_by_title, :class_name => "Post", :group => "title", :select => "title" def self.what_are_you 'a category...' diff --git a/activerecord/test/models/company.rb b/activerecord/test/models/company.rb index 1abf3f3918..0eb8ae0a15 100644 --- a/activerecord/test/models/company.rb +++ b/activerecord/test/models/company.rb @@ -55,8 +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" - has_many :clients_grouped_by_name, :class_name => "Client", :group => "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 -- cgit v1.2.3 From fcf31cb7521ba7de0aae972ac2ddfc80e3e7dfce Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Sun, 7 Sep 2008 14:42:33 +0100 Subject: Support for updating a belongs to association from the foreign key (without saving and reloading the record) Signed-off-by: Michael Koziarski [#142 state:committed] --- activerecord/lib/active_record/associations.rb | 9 ++++++++- .../test/cases/associations/belongs_to_associations_test.rb | 13 +++++++++++++ activerecord/test/cases/associations_test.rb | 12 ++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) 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/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_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 -- cgit v1.2.3 From 113de01eaf48f64d2adf9f34d699e51619af616f Mon Sep 17 00:00:00 2001 From: Rich Cavanaugh Date: Fri, 15 Aug 2008 21:49:22 -0400 Subject: Allow for the dirty tracking to work with the aliased name of aliased attributes. Signed-off-by: Michael Koziarski [#812 state:committed] --- activerecord/lib/active_record/dirty.rb | 20 +++++++++++++++++++- activerecord/test/cases/dirty_test.rb | 13 +++++++++++++ activerecord/test/models/parrot.rb | 1 + 3 files changed, 33 insertions(+), 1 deletion(-) 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/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/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 -- cgit v1.2.3 From 96055414d6197b9705e408c17236f79372a007e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Sat, 13 Sep 2008 20:12:17 +0200 Subject: Ensure Hash#except is allowed on a frozen hash. References #382 Signed-off-by: Pratik Naik --- activesupport/lib/active_support/core_ext/hash/except.rb | 2 +- activesupport/test/core_ext/hash_ext_test.rb | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/activesupport/lib/active_support/core_ext/hash/except.rb b/activesupport/lib/active_support/core_ext/hash/except.rb index f26d01553d..949976d741 100644 --- a/activesupport/lib/active_support/core_ext/hash/except.rb +++ b/activesupport/lib/active_support/core_ext/hash/except.rb @@ -10,7 +10,7 @@ module ActiveSupport #:nodoc: module Except # Returns a new hash without the given keys. def except(*keys) - clone.except!(*keys) + dup.except!(*keys) end # Replaces the hash without the given keys. diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb index 7a414e946f..44d48e7577 100644 --- a/activesupport/test/core_ext/hash_ext_test.rb +++ b/activesupport/test/core_ext/hash_ext_test.rb @@ -341,6 +341,20 @@ class HashExtTest < Test::Unit::TestCase assert_equal expected, original.except!(:c) assert_equal expected, original end + + def test_except_with_original_frozen + original = { :a => 'x', :b => 'y' } + original.freeze + assert_nothing_raised { original.except(:a) } + end + + uses_mocha 'except with expectation' do + def test_except_with_mocha_expectation_on_original + original = { :a => 'x', :b => 'y' } + original.expects(:delete).never + original.except(:a) + end + end end class IWriteMyOwnXML -- cgit v1.2.3