aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/examples/performance.rb18
-rw-r--r--activerecord/lib/active_record/aggregations.rb15
-rw-r--r--activerecord/test/cases/aggregations_test.rb18
-rw-r--r--activerecord/test/models/customer.rb5
-rw-r--r--guides/source/contributing_to_ruby_on_rails.textile32
5 files changed, 71 insertions, 17 deletions
diff --git a/actionpack/examples/performance.rb b/actionpack/examples/performance.rb
index 994e745bb0..8ea4758961 100644
--- a/actionpack/examples/performance.rb
+++ b/actionpack/examples/performance.rb
@@ -166,15 +166,7 @@ def run_all!(times, verbose)
Runner.run(:diff_100, times, verbose)
end
-unless ENV["PROFILE"]
- run_all!(1, false)
-
- (ENV["M"] || 1).to_i.times do
- $ran = []
- run_all!(N, true)
- Runner.done
- end
-else
+if ENV["PROFILE"]
Runner.run(ENV["PROFILE"].to_sym, 1, false)
require "ruby-prof"
RubyProf.start
@@ -182,4 +174,12 @@ else
result = RubyProf.stop
printer = RubyProf::CallStackPrinter.new(result)
printer.print(File.open("output.html", "w"))
+else
+ run_all!(1, false)
+
+ (ENV["M"] || 1).to_i.times do
+ $ran = []
+ run_all!(N, true)
+ Runner.done
+ end
end \ No newline at end of file
diff --git a/activerecord/lib/active_record/aggregations.rb b/activerecord/lib/active_record/aggregations.rb
index c7a329d74d..5de10a8dd6 100644
--- a/activerecord/lib/active_record/aggregations.rb
+++ b/activerecord/lib/active_record/aggregations.rb
@@ -193,7 +193,8 @@ module ActiveRecord
# * <tt>:converter</tt> - A symbol specifying the name of a class method of <tt>:class_name</tt>
# or a Proc that is called when a new value is assigned to the value object. The converter is
# passed the single value that is used in the assignment and is only called if the new value is
- # not an instance of <tt>:class_name</tt>.
+ # not an instance of <tt>:class_name</tt>. If <tt>:allow_nil</tt> is set to true, the converter
+ # can return nil to skip the assignment.
#
# Option examples:
# composed_of :temperature, :mapping => %w(reading celsius)
@@ -241,16 +242,16 @@ module ActiveRecord
def writer_method(name, class_name, mapping, allow_nil, converter)
define_method("#{name}=") do |part|
+ unless part.is_a?(class_name.constantize) || converter.nil? || part.nil?
+ part = converter.respond_to?(:call) ?
+ converter.call(part) :
+ class_name.constantize.send(converter, part)
+ end
+
if part.nil? && allow_nil
mapping.each { |pair| self[pair.first] = nil }
@aggregation_cache[name] = nil
else
- unless part.is_a?(class_name.constantize) || converter.nil?
- part = converter.respond_to?(:call) ?
- converter.call(part) :
- class_name.constantize.send(converter, part)
- end
-
mapping.each { |pair| self[pair.first] = part.send(pair.last) }
@aggregation_cache[name] = part.freeze
end
diff --git a/activerecord/test/cases/aggregations_test.rb b/activerecord/test/cases/aggregations_test.rb
index 3e0e6dce2c..5bd8f76ba2 100644
--- a/activerecord/test/cases/aggregations_test.rb
+++ b/activerecord/test/cases/aggregations_test.rb
@@ -109,6 +109,24 @@ class AggregationsTest < ActiveRecord::TestCase
assert_nil customers(:david).gps_location
end
+ def test_nil_return_from_converter_is_respected_when_allow_nil_is_true
+ customers(:david).non_blank_gps_location = ""
+ customers(:david).save
+ customers(:david).reload
+ assert_nil customers(:david).non_blank_gps_location
+ end
+
+ def test_nil_return_from_converter_results_in_failure_when_allow_nil_is_false
+ assert_raises(NoMethodError) do
+ customers(:barney).gps_location = ""
+ end
+ end
+
+ def test_do_not_run_the_converter_when_nil_was_set
+ customers(:david).non_blank_gps_location = nil
+ assert_nil Customer.gps_conversion_was_run
+ end
+
def test_custom_constructor
assert_equal 'Barney GUMBLE', customers(:barney).fullname.to_s
assert_kind_of Fullname, customers(:barney).fullname
diff --git a/activerecord/test/models/customer.rb b/activerecord/test/models/customer.rb
index 777f6b5ba0..807f25b687 100644
--- a/activerecord/test/models/customer.rb
+++ b/activerecord/test/models/customer.rb
@@ -1,7 +1,12 @@
class Customer < ActiveRecord::Base
+
+ cattr_accessor :gps_conversion_was_run
+
composed_of :address, :mapping => [ %w(address_street street), %w(address_city city), %w(address_country country) ], :allow_nil => true
composed_of :balance, :class_name => "Money", :mapping => %w(balance amount), :converter => Proc.new { |balance| balance.to_money }
composed_of :gps_location, :allow_nil => true
+ composed_of :non_blank_gps_location, :class_name => "GpsLocation", :allow_nil => true, :mapping => %w(gps_location gps_location),
+ :converter => lambda { |gps| self.gps_conversion_was_run = true; gps.blank? ? nil : GpsLocation.new(gps)}
composed_of :fullname, :mapping => %w(name to_s), :constructor => Proc.new { |name| Fullname.parse(name) }, :converter => :parse
end
diff --git a/guides/source/contributing_to_ruby_on_rails.textile b/guides/source/contributing_to_ruby_on_rails.textile
index df475a2359..a2254a550c 100644
--- a/guides/source/contributing_to_ruby_on_rails.textile
+++ b/guides/source/contributing_to_ruby_on_rails.textile
@@ -343,9 +343,39 @@ h4. Commit Your Changes
When you're happy with the code on your computer, you need to commit the changes to git:
<shell>
-$ git commit -a -m "Here is a commit message on what I changed in this commit"
+$ git commit -a
</shell>
+At this point, your editor should be fired up and you can write a message for this commit. Well formatted and descriptive commit messages are extremely helpful for the others, especially when figuring out why given change was made, so please take the time to write it.
+
+Good commit message should be formatted according to the following example:
+
+<plain>
+Short summary (ideally 50 characters or less)
+
+More detailed description, if necessary. It should be wrapped to 72
+characters. Try to be as descriptive as you can, even if you think that
+the commit content is obvious, it may not be obvious to others. You
+should add such description also if it's already present in bug tracker,
+it should not be necessary to visit a webpage to check the history.
+
+Description can have multiple paragraps and you can use code examples
+inside, just indent it with 4 spaces:
+
+ class PostsController
+ def index
+ respond_with Post.limit(10)
+ end
+ end
+
+You can also add bullet points:
+
+- you can use dashes or asterisks
+
+- also, try to indent next line of a point for readability, if it's too
+ long to fit in 72 characters
+</plain>
+
TIP. Please squash your commits into a single commit when appropriate. This simplifies future cherry picks, and also keeps the git log clean.
h4. Update Master