aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/text_helper.rb2
-rw-r--r--actionpack/test/template/form_helper_test.rb11
-rw-r--r--actionpack/test/template/text_helper_test.rb1
-rw-r--r--activerecord/lib/active_record/associations/association_proxy.rb3
-rw-r--r--activerecord/lib/active_record/dirty.rb32
-rw-r--r--activerecord/test/cases/active_schema_test_mysql.rb73
-rw-r--r--activerecord/test/cases/dirty_test.rb18
-rw-r--r--activerecord/test/cases/migration_test.rb4
-rw-r--r--railties/lib/commands/console.rb4
-rw-r--r--railties/lib/commands/servers/lighttpd.rb2
-rw-r--r--railties/lib/commands/servers/mongrel.rb2
-rw-r--r--railties/lib/commands/servers/webrick.rb2
-rw-r--r--railties/lib/initializer.rb4
-rw-r--r--railties/lib/rails/mongrel_server/commands.rb2
15 files changed, 112 insertions, 50 deletions
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index 940f1c9b5d..3d80d508b9 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -635,6 +635,8 @@ module ActionView
value != 0
when String
value == checked_value
+ when Array
+ value.include?(checked_value)
else
value.to_i != 0
end
diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb
index 55d2a68327..b710157f51 100644
--- a/actionpack/lib/action_view/helpers/text_helper.rb
+++ b/actionpack/lib/action_view/helpers/text_helper.rb
@@ -464,7 +464,7 @@ module ActionView
[-\w]+ # subdomain or domain
(?:\.[-\w]+)* # remaining subdomains or domain
(?::\d+)? # port
- (?:/(?:(?:[~\w\+@%=-]|(?:[,.;:][^\s$]))+)?)* # path
+ (?:/(?:(?:[~\w\+@%=\(\)-]|(?:[,.;:][^\s$]))+)?)* # path
(?:\?[\w\+@%&=.;-]+)? # query string
(?:\#[\w\-]*)? # trailing anchor
)
diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb
index 4538b6dc6f..af99e6243d 100644
--- a/actionpack/test/template/form_helper_test.rb
+++ b/actionpack/test/template/form_helper_test.rb
@@ -181,6 +181,17 @@ class FormHelperTest < ActionView::TestCase
'<input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
check_box("post", "secret?")
)
+
+ @post.secret = ['0']
+ assert_dom_equal(
+ '<input id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
+ check_box("post", "secret")
+ )
+ @post.secret = ['1']
+ assert_dom_equal(
+ '<input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
+ check_box("post", "secret")
+ )
end
def test_check_box_with_explicit_checked_and_unchecked_values
diff --git a/actionpack/test/template/text_helper_test.rb b/actionpack/test/template/text_helper_test.rb
index 337697bf5c..36c939f761 100644
--- a/actionpack/test/template/text_helper_test.rb
+++ b/actionpack/test/template/text_helper_test.rb
@@ -186,6 +186,7 @@ class TextHelperTest < ActionView::TestCase
http://en.wikipedia.org/wiki/Wikipedia:Today%27s_featured_picture_%28animation%29/January_20%2C_2007
http://www.mail-archive.com/rails@lists.rubyonrails.org/
http://www.amazon.com/Testing-Equal-Sign-In-Path/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1198861734&sr=8-1
+ http://en.wikipedia.org/wiki/Sprite_(computer_graphics)
)
urls.each do |url|
diff --git a/activerecord/lib/active_record/associations/association_proxy.rb b/activerecord/lib/active_record/associations/association_proxy.rb
index ec16af3897..11c64243a2 100644
--- a/activerecord/lib/active_record/associations/association_proxy.rb
+++ b/activerecord/lib/active_record/associations/association_proxy.rb
@@ -210,7 +210,8 @@ module ActiveRecord
def raise_on_type_mismatch(record)
unless record.is_a?(@reflection.klass)
- raise ActiveRecord::AssociationTypeMismatch, "#{@reflection.klass} expected, got #{record.class}"
+ message = "#{@reflection.class_name}(##{@reflection.klass.object_id}) expected, got #{record.class}(##{record.class.object_id})"
+ raise ActiveRecord::AssociationTypeMismatch, message
end
end
diff --git a/activerecord/lib/active_record/dirty.rb b/activerecord/lib/active_record/dirty.rb
index 6034963811..8fdc763292 100644
--- a/activerecord/lib/active_record/dirty.rb
+++ b/activerecord/lib/active_record/dirty.rb
@@ -40,6 +40,7 @@ module ActiveRecord
base.alias_method_chain :save, :dirty
base.alias_method_chain :save!, :dirty
base.alias_method_chain :update, :dirty
+ base.alias_method_chain :reload, :dirty
base.superclass_delegating_accessor :partial_updates
base.partial_updates = false
@@ -84,6 +85,13 @@ module ActiveRecord
status
end
+ # <tt>reload</tt> the record and clears changed attributes.
+ def reload_with_dirty(*args) #:nodoc:
+ record = reload_without_dirty(*args)
+ changed_attributes.clear
+ record
+ end
+
private
# Map of change attr => original value.
def changed_attributes
@@ -117,14 +125,7 @@ module ActiveRecord
# The attribute already has an unsaved change.
unless changed_attributes.include?(attr)
old = clone_attribute_value(:read_attribute, attr)
-
- # Remember the original value if it's different.
- typecasted = if column = column_for_attribute(attr)
- column.type_cast(value)
- else
- value
- end
- changed_attributes[attr] = old unless old == typecasted
+ changed_attributes[attr] = old if field_changed?(attr, old, value)
end
# Carry on.
@@ -138,5 +139,20 @@ module ActiveRecord
update_without_dirty
end
end
+
+ def field_changed?(attr, old, value)
+ if column = column_for_attribute(attr)
+ if column.type == :integer && column.null && old.nil?
+ # For nullable integer columns, NULL gets stored in database for blank (i.e. '') values.
+ # Hence we don't record it as a change if the value changes from nil to ''.
+ value = nil if value.blank?
+ else
+ value = column.type_cast(value)
+ end
+ end
+
+ old != value
+ end
+
end
end
diff --git a/activerecord/test/cases/active_schema_test_mysql.rb b/activerecord/test/cases/active_schema_test_mysql.rb
index ddf3e82162..2a42dc3517 100644
--- a/activerecord/test/cases/active_schema_test_mysql.rb
+++ b/activerecord/test/cases/active_schema_test_mysql.rb
@@ -40,47 +40,56 @@ class ActiveSchemaTest < ActiveRecord::TestCase
end
def test_add_timestamps
- #we need to actually modify some data, so we make execute to point to the original method
- ActiveRecord::ConnectionAdapters::MysqlAdapter.class_eval do
- alias_method :execute_with_stub, :execute
- alias_method :execute, :execute_without_stub
- end
- ActiveRecord::Base.connection.create_table :delete_me do |t|
- end
- ActiveRecord::Base.connection.add_timestamps :delete_me
- assert_equal ActiveRecord::Base.connection.execute("SHOW FIELDS FROM delete_me where FIELD='updated_at' AND TYPE='datetime'").num_rows, 1
- assert_equal ActiveRecord::Base.connection.execute("SHOW FIELDS FROM delete_me where FIELD='created_at' AND TYPE='datetime'").num_rows, 1
- ensure
- ActiveRecord::Base.connection.drop_table :delete_me rescue nil
- #before finishing, we restore the alias to the mock-up method
- ActiveRecord::ConnectionAdapters::MysqlAdapter.class_eval do
- alias_method :execute, :execute_with_stub
+ with_real_execute do
+ begin
+ ActiveRecord::Base.connection.create_table :delete_me do |t|
+ end
+ ActiveRecord::Base.connection.add_timestamps :delete_me
+ assert column_present?('delete_me', 'updated_at', 'datetime')
+ assert column_present?('delete_me', 'created_at', 'datetime')
+ ensure
+ ActiveRecord::Base.connection.drop_table :delete_me rescue nil
+ end
end
end
def test_remove_timestamps
- #we need to actually modify some data, so we make execute to point to the original method
- ActiveRecord::ConnectionAdapters::MysqlAdapter.class_eval do
- alias_method :execute_with_stub, :execute
- alias_method :execute, :execute_without_stub
- end
- ActiveRecord::Base.connection.create_table :delete_me do |t|
- t.timestamps
- end
- ActiveRecord::Base.connection.remove_timestamps :delete_me
- assert_equal ActiveRecord::Base.connection.execute("SHOW FIELDS FROM delete_me where FIELD='updated_at' AND TYPE='datetime'").num_rows, 0
- assert_equal ActiveRecord::Base.connection.execute("SHOW FIELDS FROM delete_me where FIELD='created_at' AND TYPE='datetime'").num_rows, 0
- ensure
- ActiveRecord::Base.connection.drop_table :delete_me rescue nil
- #before finishing, we restore the alias to the mock-up method
- ActiveRecord::ConnectionAdapters::MysqlAdapter.class_eval do
- alias_method :execute, :execute_with_stub
+ with_real_execute do
+ begin
+ ActiveRecord::Base.connection.create_table :delete_me do |t|
+ t.timestamps
+ end
+ ActiveRecord::Base.connection.remove_timestamps :delete_me
+ assert !column_present?('delete_me', 'updated_at', 'datetime')
+ assert !column_present?('delete_me', 'created_at', 'datetime')
+ ensure
+ ActiveRecord::Base.connection.drop_table :delete_me rescue nil
+ end
end
end
-
private
+ def with_real_execute
+ #we need to actually modify some data, so we make execute point to the original method
+ ActiveRecord::ConnectionAdapters::MysqlAdapter.class_eval do
+ alias_method :execute_with_stub, :execute
+ alias_method :execute, :execute_without_stub
+ end
+ yield
+ ensure
+ #before finishing, we restore the alias to the mock-up method
+ ActiveRecord::ConnectionAdapters::MysqlAdapter.class_eval do
+ alias_method :execute, :execute_with_stub
+ end
+ end
+
+
def method_missing(method_symbol, *arguments)
ActiveRecord::Base.connection.send(method_symbol, *arguments)
end
+
+ def column_present?(table_name, column_name, type)
+ results = ActiveRecord::Base.connection.select_all("SHOW FIELDS FROM #{table_name} LIKE '#{column_name}'")
+ results.first && results.first['Type'] == type
+ end
end
diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb
index 1266eb5036..c011ffaf57 100644
--- a/activerecord/test/cases/dirty_test.rb
+++ b/activerecord/test/cases/dirty_test.rb
@@ -44,6 +44,16 @@ class DirtyTest < ActiveRecord::TestCase
assert_nil pirate.catchphrase_change
end
+ def test_nullable_integer_not_marked_as_changed_if_new_value_is_blank
+ pirate = Pirate.new
+
+ ["", nil].each do |value|
+ pirate.parrot_id = value
+ assert !pirate.parrot_id_changed?
+ assert_nil pirate.parrot_id_change
+ end
+ end
+
def test_object_should_be_changed_if_any_attribute_is_changed
pirate = Pirate.new
assert !pirate.changed?
@@ -127,6 +137,14 @@ class DirtyTest < ActiveRecord::TestCase
check_pirate_after_save_failure(pirate)
end
+ def test_reload_should_clear_changed_attributes
+ pirate = Pirate.create!(:catchphrase => "shiver me timbers")
+ pirate.catchphrase = "*hic*"
+ assert pirate.changed?
+ pirate.reload
+ assert !pirate.changed?
+ end
+
private
def with_partial_updates(klass, on = true)
old = klass.partial_updates?
diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb
index 527856b4c0..f36255e209 100644
--- a/activerecord/test/cases/migration_test.rb
+++ b/activerecord/test/cases/migration_test.rb
@@ -281,7 +281,7 @@ if ActiveRecord::Base.connection.supports_migrations?
# Do a manual insertion
if current_adapter?(:OracleAdapter)
Person.connection.execute "insert into people (id, wealth) values (people_seq.nextval, 12345678901234567890.0123456789)"
- elsif current_adapter?(:OpenBaseAdapter)
+ elsif current_adapter?(:OpenBaseAdapter) || (current_adapter?(:MysqlAdapter) && Mysql.client_version < 50003) #before mysql 5.0.3 decimals stored as strings
Person.connection.execute "insert into people (wealth) values ('12345678901234567890.0123456789')"
else
Person.connection.execute "insert into people (wealth) values (12345678901234567890.0123456789)"
@@ -384,7 +384,7 @@ if ActiveRecord::Base.connection.supports_migrations?
assert_not_equal "Z", bob.moment_of_truth.zone
# US/Eastern is -5 hours from GMT
assert_equal Rational(-5, 24), bob.moment_of_truth.offset
- assert_equal "-05:00", bob.moment_of_truth.zone
+ assert_match /\A-05:?00\Z/, bob.moment_of_truth.zone #ruby 1.8.6 uses HH:MM, prior versions use HHMM
assert_equal DateTime::ITALY, bob.moment_of_truth.start
end
end
diff --git a/railties/lib/commands/console.rb b/railties/lib/commands/console.rb
index edffe4f1e6..2b9d92f647 100644
--- a/railties/lib/commands/console.rb
+++ b/railties/lib/commands/console.rb
@@ -24,9 +24,9 @@ ENV['RAILS_ENV'] = case ARGV.first
end
if options[:sandbox]
- puts "Loading #{ENV['RAILS_ENV']} environment in sandbox (Rails #{Rails::VERSION::STRING})"
+ puts "Loading #{ENV['RAILS_ENV']} environment in sandbox (Rails #{Rails.version})"
puts "Any modifications you make will be rolled back on exit"
else
- puts "Loading #{ENV['RAILS_ENV']} environment (Rails #{Rails::VERSION::STRING})"
+ puts "Loading #{ENV['RAILS_ENV']} environment (Rails #{Rails.version})"
end
exec "#{options[:irb]} #{libs} --simple-prompt"
diff --git a/railties/lib/commands/servers/lighttpd.rb b/railties/lib/commands/servers/lighttpd.rb
index 07d4f9d0bf..c9d13e86f3 100644
--- a/railties/lib/commands/servers/lighttpd.rb
+++ b/railties/lib/commands/servers/lighttpd.rb
@@ -62,7 +62,7 @@ config = IO.read(config_file)
default_port, default_ip = 3000, '0.0.0.0'
port = config.scan(/^\s*server.port\s*=\s*(\d+)/).first rescue default_port
ip = config.scan(/^\s*server.bind\s*=\s*"([^"]+)"/).first rescue default_ip
-puts "=> Rails application starting on http://#{ip || default_ip}:#{port || default_port}"
+puts "=> Rails #{Rails.version} application starting on http://#{ip || default_ip}:#{port || default_port}"
tail_thread = nil
diff --git a/railties/lib/commands/servers/mongrel.rb b/railties/lib/commands/servers/mongrel.rb
index f59265e698..7bb110f63a 100644
--- a/railties/lib/commands/servers/mongrel.rb
+++ b/railties/lib/commands/servers/mongrel.rb
@@ -32,7 +32,7 @@ ARGV.clone.options do |opts|
opts.parse!
end
-puts "=> Rails application starting on http://#{OPTIONS[:ip]}:#{OPTIONS[:port]}"
+puts "=> Rails #{Rails.version} application starting on http://#{OPTIONS[:ip]}:#{OPTIONS[:port]}"
parameters = [
"start",
diff --git a/railties/lib/commands/servers/webrick.rb b/railties/lib/commands/servers/webrick.rb
index b950376150..18c8897cc8 100644
--- a/railties/lib/commands/servers/webrick.rb
+++ b/railties/lib/commands/servers/webrick.rb
@@ -61,6 +61,6 @@ require 'webrick_server'
OPTIONS['working_directory'] = File.expand_path(RAILS_ROOT)
-puts "=> Rails application started on http://#{OPTIONS[:ip]}:#{OPTIONS[:port]}"
+puts "=> Rails #{Rails.version} application started on http://#{OPTIONS[:ip]}:#{OPTIONS[:port]}"
puts "=> Ctrl-C to shutdown server; call with --help for options" if OPTIONS[:server_type] == WEBrick::SimpleServer
DispatchServlet.dispatch(OPTIONS)
diff --git a/railties/lib/initializer.rb b/railties/lib/initializer.rb
index 150e76af77..98cc206765 100644
--- a/railties/lib/initializer.rb
+++ b/railties/lib/initializer.rb
@@ -43,6 +43,10 @@ module Rails
RAILS_CACHE
end
+ def version
+ VERSION::STRING
+ end
+
def public_path
@@public_path ||= self.root ? File.join(self.root, "public") : "public"
end
diff --git a/railties/lib/rails/mongrel_server/commands.rb b/railties/lib/rails/mongrel_server/commands.rb
index 3786a56fde..0a92f418ad 100644
--- a/railties/lib/rails/mongrel_server/commands.rb
+++ b/railties/lib/rails/mongrel_server/commands.rb
@@ -119,7 +119,7 @@ module Rails
config = RailsConfigurator.new(settings) do
defaults[:log] = $stdout if defaults[:environment] == 'development'
- Mongrel.log("=> Rails application starting on http://#{defaults[:host]}:#{defaults[:port]}")
+ Mongrel.log("=> Rails #{Rails.version} application starting on http://#{defaults[:host]}:#{defaults[:port]}")
unless defaults[:daemon]
Mongrel.log("=> Call with -d to detach")