Permalink
Browse files

Fix error when using `with_options` with lambda.

It was causing error when using `with_options` passing a lambda as its
last argument.

    class User < ActiveRecord::Base
      with_options dependent: :destroy do |assoc|
        assoc.has_many :profiles, -> { where(active: true) }
      end
    end

It was happening because the `option_merger` was taking the last
argument and checking if it was a Hash. This breaks the HasMany usage,
because its last argument can be a Hash or a Proc.

As the behavior described in this test:
https://github.com/rails/rails/blob/master/activesupport/test/option_merger_test.rb#L69
the method will only accept the lambda, this way it will keep the expected behavior. See 9eaa0a3
  • Loading branch information...
1 parent 7531404 commit db5d26c9d70fb72b8aa3ea98709224dd13800024 @laurocaetano laurocaetano committed Apr 2, 2014
View
6 activerecord/CHANGELOG.md
@@ -1,3 +1,9 @@
+* Fixed error when using `with_options` with lambda.
+
+ Fixes #9805.
+
+ *Lauro Caetano*
+
* Treat blank UUID values as `nil`.
Example:
View
9 activerecord/test/cases/associations/has_many_associations_test.rb
@@ -24,6 +24,8 @@
require 'models/speedometer'
require 'models/reference'
require 'models/job'
+require 'models/college'
+require 'models/student'
class HasManyAssociationsTestForReorderWithJoinDependency < ActiveRecord::TestCase
fixtures :authors, :posts, :comments
@@ -65,6 +67,13 @@ def test_anonymous_has_many
dev.developer_projects.map(&:project_id).sort
end
+ def test_has_many_build_with_options
+ college = College.create(name: 'UFMT')
+ student = Student.create(active: true, college_id: college.id, name: 'Sarah')
+
+ assert_equal college.students, Student.where(active: true, college_id: college.id)
+ end
+
def test_create_from_association_should_respect_default_scope
car = Car.create(:name => 'honda')
assert_equal 'honda', car.name
View
5 activerecord/test/models/college.rb
@@ -1,5 +1,10 @@
require_dependency 'models/arunit2_model'
+require 'active_support/core_ext/object/with_options'
class College < ARUnit2Model
has_many :courses
+
+ with_options dependent: :destroy do |assoc|
+ assoc.has_many :students, -> { where(active: true) }
+ end
end
View
1 activerecord/test/models/student.rb
@@ -1,3 +1,4 @@
class Student < ActiveRecord::Base
has_and_belongs_to_many :lessons
+ belongs_to :college
end
View
2 activerecord/test/schema/schema.rb
@@ -638,6 +638,8 @@ def create_table(*args, &block)
create_table :students, force: true do |t|
t.string :name
+ t.boolean :active
+ t.integer :college_id
end
create_table :subscribers, force: true, id: false do |t|
View
2 activesupport/lib/active_support/option_merger.rb
@@ -12,7 +12,7 @@ def initialize(context, options)
private
def method_missing(method, *arguments, &block)
- if arguments.last.is_a?(Proc)
+ if arguments.first.is_a?(Proc)
proc = arguments.pop
arguments << lambda { |*args| @options.deep_merge(proc.call(*args)) }
else

0 comments on commit db5d26c

Please sign in to comment.