Disallow self- and descendant-reference for base/parent
This commit is contained in:
		
							parent
							
								
									17b4e4f8a7
								
							
						
					
					
						commit
						0652d4a89b
					
				@ -8,6 +8,10 @@ class Quantity < ApplicationRecord
 | 
			
		||||
 | 
			
		||||
  validate if: ->{ parent.present? } do
 | 
			
		||||
    errors.add(:parent, :user_mismatch) unless user == parent.user
 | 
			
		||||
    errors.add(:parent, :self_reference) if self == parent
 | 
			
		||||
  end
 | 
			
		||||
  validate if: ->{ parent.present? }, on: :update do
 | 
			
		||||
    errors.add(:parent, :descendant_reference) if ancestor_of?(parent)
 | 
			
		||||
  end
 | 
			
		||||
  validates :name, presence: true, uniqueness: {scope: [:user_id, :parent_id]},
 | 
			
		||||
    length: {maximum: type_for_attribute(:name).limit}
 | 
			
		||||
@ -99,4 +103,15 @@ class Quantity < ApplicationRecord
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def ancestor_of?(descendant)
 | 
			
		||||
    quantities = Quantity.arel_table
 | 
			
		||||
    ancestors = Arel::Table.new('ancestors')
 | 
			
		||||
    Quantity.with_recursive(ancestors: [
 | 
			
		||||
      user.quantities.where(id: descendant.id),
 | 
			
		||||
      user.quantities.joins(quantities.create_join(
 | 
			
		||||
          ancestors, quantities.create_on(quantities[:id].eq(ancestors[:parent_id]))
 | 
			
		||||
      ))
 | 
			
		||||
    ]).from(ancestors).exists?(ancestors: {id: id})
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@ -7,6 +7,7 @@ class Unit < ApplicationRecord
 | 
			
		||||
 | 
			
		||||
  validate if: ->{ base.present? } do
 | 
			
		||||
    errors.add(:base, :user_mismatch) unless user == base.user
 | 
			
		||||
    errors.add(:base, :self_reference) if self == base
 | 
			
		||||
    errors.add(:base, :multilevel_nesting) if base.base.present?
 | 
			
		||||
  end
 | 
			
		||||
  validates :symbol, presence: true, uniqueness: {scope: :user_id},
 | 
			
		||||
 | 
			
		||||
@ -23,11 +23,18 @@ en:
 | 
			
		||||
          attributes:
 | 
			
		||||
            base:
 | 
			
		||||
              multilevel_nesting: has to be a top-level unit
 | 
			
		||||
              self_reference: of an unit cannot be the unit itself
 | 
			
		||||
              user_mismatch: has to belong to the same user as unit
 | 
			
		||||
            multiplier:
 | 
			
		||||
              equal_to: for a top-level unit has to be 1
 | 
			
		||||
            symbol:
 | 
			
		||||
              taken: has to be unique
 | 
			
		||||
        quantity:
 | 
			
		||||
          attributes:
 | 
			
		||||
            parent:
 | 
			
		||||
              descendant_reference: of the quantity cannot be its descendant
 | 
			
		||||
              self_reference: of the quantitiy cannot be the quantity itself
 | 
			
		||||
              user_mismatch: has to belong to the same user as quantity
 | 
			
		||||
  actioncontroller:
 | 
			
		||||
    exceptions:
 | 
			
		||||
      status:
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user