Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #7449 from Mik-die/nested-limits

Allow to pass Symbol or Proc into :limit option of #accepts_nested_attributes_for
  • Loading branch information...
commit f0c867fb50642af38d3410c18b5e6f4167b8ff3b 2 parents af31cf0 + ff8f759
@rafaelfranca rafaelfranca authored
View
4 activerecord/CHANGELOG.md
@@ -1,5 +1,9 @@
## Rails 4.0.0 (unreleased) ##
+* Allow to pass Symbol or Proc into :limit option of #accepts_nested_attributes_for
+
+ *Mikhail Dieterle*
+
* ActiveRecord::SessionStore has been extracted from Active Record as `activerecord-session_store`
gem. Please read the `README.md` file on the gem for the usage. *Prem Sichanugrist*
View
16 activerecord/lib/active_record/nested_attributes.rb
@@ -245,7 +245,8 @@ module ClassMethods
# any value for _destroy.
# [:limit]
# Allows you to specify the maximum number of the associated records that
- # can be processed with the nested attributes. If the size of the
+ # can be processed with the nested attributes. Limit also can be specified as a
+ # Proc or a Symbol pointing to a method that should return number. If the size of the
# nested attributes array exceeds the specified limit, NestedAttributes::TooManyRecords
# exception is raised. If omitted, any number associations can be processed.
# Note that the :limit option is only applicable to one-to-many associations.
@@ -388,8 +389,17 @@ def assign_nested_attributes_for_collection_association(association_name, attrib
raise ArgumentError, "Hash or Array expected, got #{attributes_collection.class.name} (#{attributes_collection.inspect})"
end
- if options[:limit] && attributes_collection.size > options[:limit]
- raise TooManyRecords, "Maximum #{options[:limit]} records are allowed. Got #{attributes_collection.size} records instead."
+ limit = case options[:limit]
+ when Symbol
+ send(options[:limit])
+ when Proc
+ options[:limit].call
+ else
+ options[:limit]
+ end
+
+ if limit && attributes_collection.size > limit
+ raise TooManyRecords, "Maximum #{limit} records are allowed. Got #{attributes_collection.size} records instead."
end
if attributes_collection.is_a? Hash
View
38 activerecord/test/cases/nested_attributes_test.rb
@@ -846,13 +846,7 @@ def setup
include NestedAttributesOnACollectionAssociationTests
end
-class TestNestedAttributesLimit < ActiveRecord::TestCase
- def setup
- Pirate.accepts_nested_attributes_for :parrots, :limit => 2
-
- @pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?")
- end
-
+module NestedAttributesLimitTests
def teardown
Pirate.accepts_nested_attributes_for :parrots, :allow_destroy => true, :reject_if => proc { |attributes| attributes.empty? }
end
@@ -876,6 +870,36 @@ def test_limit_with_exceeding_records
end
end
+class TestNestedAttributesLimitNumeric < ActiveRecord::TestCase
+ def setup
+ Pirate.accepts_nested_attributes_for :parrots, :limit => 2
+
+ @pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?")
+ end
+
+ include NestedAttributesLimitTests
+end
+
+class TestNestedAttributesLimitSymbol < ActiveRecord::TestCase
+ def setup
+ Pirate.accepts_nested_attributes_for :parrots, :limit => :parrots_limit
+
+ @pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?", :parrots_limit => 2)
+ end
+
+ include NestedAttributesLimitTests
+end
+
+class TestNestedAttributesLimitProc < ActiveRecord::TestCase
+ def setup
+ Pirate.accepts_nested_attributes_for :parrots, :limit => proc { 2 }
+
+ @pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?")
+ end
+
+ include NestedAttributesLimitTests
+end
+
class TestNestedAttributesWithNonStandardPrimaryKeys < ActiveRecord::TestCase
fixtures :owners, :pets
View
2  activerecord/test/models/pirate.rb
@@ -53,7 +53,7 @@ def reject_empty_ships_on_create(attributes)
attributes.delete('_reject_me_if_new').present? && !persisted?
end
- attr_accessor :cancel_save_from_callback
+ attr_accessor :cancel_save_from_callback, :parrots_limit
before_save :cancel_save_callback_method, :if => :cancel_save_from_callback
def cancel_save_callback_method
false
Please sign in to comment.
Something went wrong with that request. Please try again.