module Collectible::Collection::EnsuresItemEligibility
Constants
- ENSURE_TYPE_EQUALITY
Private Instance Methods
allow_item(&block)
click to toggle source
@example
# Allows any item that responds to :even? with a truthy value allow_item { |item| item.even? }
for block { |item| … } @yield [*] Yields each inserted item to the provided block. The item will only be allowed into
the collection if the block resolves to a truthy value; otherwise, an error is raised. The block shares the context of the collection +instance+, not the class.
# File lib/collectible/collection/ensures_item_eligibility.rb, line 82 def allow_item(&block) raise Collectible::TypeEnforcementAlreadyDefined if item_enforcement.present? raise ArgumentError, "must provide a block" unless block_given? self.item_enforcement = block end
allows_item?(item)
click to toggle source
@param item [*] @return [Boolean]
# File lib/collectible/collection/ensures_item_eligibility.rb, line 33 def allows_item?(item) if ensure_item_validity_with.respond_to?(:call) instance_exec(item, &ensure_item_validity_with) elsif ensure_item_validity_with.present? item.class <= ensure_item_validity_with else true end end
ensure_allowed_in_collection!(*new_items)
click to toggle source
Raises an error if any items fail the class' item validity block/class
# File lib/collectible/collection/ensures_item_eligibility.rb, line 21 def ensure_allowed_in_collection!(*new_items) ensure_type_equality!(*new_items) and return if ensures_type_equality? invalid_items = new_items.flatten.reject { |item| allows_item?(item) } return if invalid_items.empty? raise Collectible::ItemNotAllowedError, "not allowed: #{invalid_items.first(3).map(&:inspect).join(", ")}#{"..." if invalid_items.length > 3}" end
ensure_item_validity_before(*methods)
click to toggle source
Inserts a check before each of the methods provided to validate inserted objects
@param *methods [Array<Symbol>]
Calls superclass method
# File lib/collectible/collection/ensures_item_eligibility.rb, line 118 def ensure_item_validity_before(*methods) methods.each do |method_name| around_method(method_name, prevent_double_wrapping_for: "EnsureItemValidity") do |*items| ensure_allowed_in_collection!(items) super(*items) end end end
ensure_item_validity_with()
click to toggle source
@return [Class, Proc] Either a class that all collection items must belong to,
or a proc that validates each item as it is inserted.
# File lib/collectible/collection/ensures_item_eligibility.rb, line 67 def ensure_item_validity_with item_enforcement || (superclass.ensure_item_validity_with if superclass.respond_to?(:ensure_item_validity_with, true)) end
ensure_type_equality!(*new_items)
click to toggle source
# File lib/collectible/collection/ensures_item_eligibility.rb, line 48 def ensure_type_equality!(*new_items) new_items = new_items.flatten first_item = items.blank? ? new_items.first : items.first new_items.each do |item| next if item.class == first_item.class raise Collectible::ItemTypeMismatchError, "item mismatch: #{first_item.inspect}, #{item.inspect}" end end
ensures_item_class(klass)
click to toggle source
@example
# Allows any item where item.class <= TargetDate ensures_item_class TargetDate
@param klass [Class] A specific class all items are expected to be. Items of this type will be
allowed into collection; otherwise, an error is raised.
# File lib/collectible/collection/ensures_item_eligibility.rb, line 95 def ensures_item_class(klass) raise Collectible::TypeEnforcementAlreadyDefined if item_enforcement.present? self.item_enforcement = klass end
ensures_type_equality()
click to toggle source
Allows any object initially, but any subsequent item must be of the same class
@example
collection << Meal.first => #<ApplicationCollection items: [ #<Meal id: 1> ] collection << User.first => Collectible::ItemNotAllowedError: not allowed: #<User id: 1>
# File lib/collectible/collection/ensures_item_eligibility.rb, line 109 def ensures_type_equality raise Collectible::TypeEnforcementAlreadyDefined if item_enforcement.present? self.item_enforcement = ENSURE_TYPE_EQUALITY end
ensures_type_equality?()
click to toggle source
@return [Boolean]
# File lib/collectible/collection/ensures_item_eligibility.rb, line 44 def ensures_type_equality? ensure_item_validity_with == ENSURE_TYPE_EQUALITY end
item_class()
click to toggle source
@return [Class] The class or superclass of all items in the collection
# File lib/collectible/collection/ensures_item_eligibility.rb, line 61 def item_class item_enforcement.is_a?(Class) ? item_enforcement : name.gsub(%r{Collection.*}, "").safe_constantize end