Multiple block args to ActiveRecord association proxy are splatted incorrectly
------------------------------------------------------------------------------
Key: JRUBY-4831
URL: http://jira.codehaus.org/browse/JRUBY-4831
Project: JRuby
Issue Type: Bug
Affects Versions: JRuby 1.5
Environment: Tested on Ubuntu 10.04 and Windows Server 2003
Reporter: Colin Strasser
Assignee: Thomas E Enebo
I added the following test cases to
activerecord-2.3.8/test/cases/associations/has_many_associations_test.rb. These
fail for JRuby but pass for MRI.
def test_normal_method_call_in_association_proxy_with_multiple_block_args
elem = nil
Comment.all.each_with_index {|e, i| elem = e}
assert_kind_of(Comment, elem)
Post.find(:first).comments.each_with_index {|e, i| elem = e}
assert_kind_of(Comment, elem) # FAILS in JRuby; elem is an Array
end
def test_instance_eval_in_association_proxy_with_multiple_block_args
elem = nil
Comment.all.each_with_index {|e, i| elem = e}
assert_kind_of(Comment, elem)
Post.find(:first).comments.each_with_index {|e, i| elem = e}
assert_kind_of(Comment, elem) # FAILS in JRuby; elem is an Array
end
The problem seems very similar to http://jira.codehaus.org/browse/JRUBY-2801
(Incorrect argument splatting/array construction passing splatted args through
a block that yields), but in the context of Object#send with a final &block
argument rather than an explicit block.
Below is the commit that introduced the issue to ActiveRecord. Reverting the
implementation of method_missing fixes my test cases but breaks the ones from
the commit. I'm filing this as a JRuby bug rather than an ActiveRecord one
since under MRI the code behaves as expected.
administra...@fivp-dev /c/dev/FIVP/rails/fivp/vendor/rails
$ git show
commit 2f1ded306728ce8ff614e09a113398328e7fe6ca
Author: Mat Brown <[email protected]>
Date: Thu Oct 22 10:20:44 2009 -0400
Fix instance_eval calls to association proxies
In the current stable,
ActiveRecord::Associations::AssociationProxy#method_missing calls yield() if a
block is given, causing the block to always be evaluated in its calling
context. However, in the case of instance_eval, correct behavior requires that
the block be passed directly to the @target, rather than being evaluated inside
a different block. Incidentally, this also simplifies the code slightly.
[#3412 state:committed]
Signed-off-by: Jeremy Kemper <[email protected]>
diff --git a/activerecord/lib/active_record/associations/association_proxy.rb
b/activerecord/lib/active_record/associations/association_
index 3058e28..e1fce9a 100644
--- a/activerecord/lib/active_record/associations/association_proxy.rb
+++ b/activerecord/lib/active_record/associations/association_proxy.rb
@@ -208,14 +208,10 @@ module ActiveRecord
private
# Forwards any missing method call to the \target.
- def method_missing(method, *args)
+ def method_missing(method, *args, &block)
if load_target
if @target.respond_to?(method)
- if block_given?
- @target.send(method, *args) { |*block_args|
yield(*block_args) }
- else
- @target.send(method, *args)
- end
+ @target.send(method, *args, &block)
else
super
end
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb
b/activerecord/test/cases/associations/has_many_associat
index eee80b2..94cdb52 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -1130,5 +1130,13 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
client = firm.clients_using_primary_key.create!(:name => 'test')
assert_equal firm.name, client.firm_name
end
+
+ def test_normal_method_call_in_association_proxy
+ assert_equal 'Welcome to the weblog', Comment.all.map { |comment|
comment.post }.first.title
+ end
+
+ def test_instance_eval_in_association_proxy
+ assert_equal 'Welcome to the weblog', Comment.all.map { |comment|
comment.post }.first.instance_eval{title}
+ end
end
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://jira.codehaus.org/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email