forked from fixin.me/fixin.me
Use callbacks instead of attribute methods to update cached values
This commit is contained in:
parent
fe66522c21
commit
d1593df0e0
@ -18,7 +18,11 @@ class Quantity < ApplicationRecord
|
|||||||
length: {maximum: type_for_attribute(:name).limit}
|
length: {maximum: type_for_attribute(:name).limit}
|
||||||
validates :description, length: {maximum: type_for_attribute(:description).limit}
|
validates :description, length: {maximum: type_for_attribute(:description).limit}
|
||||||
|
|
||||||
# Update `depth`s of progenies after parent change
|
# Update :depths of progenies after parent change
|
||||||
|
before_update if: :parent_changed? do
|
||||||
|
self[:depth] = parent&.depth&.succ || 0
|
||||||
|
end
|
||||||
|
|
||||||
after_update if: :depth_previously_changed? do
|
after_update if: :depth_previously_changed? do
|
||||||
quantities = Quantity.arel_table
|
quantities = Quantity.arel_table
|
||||||
selected = Arel::Table.new('selected')
|
selected = Arel::Table.new('selected')
|
||||||
@ -45,32 +49,28 @@ class Quantity < ApplicationRecord
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
after_update if: -> { name_previously_changed? || parent_previously_changed? } do
|
# Update :pathnames of progenies after parent/name change
|
||||||
|
PATHNAME_DELIMITER = ' → '
|
||||||
|
|
||||||
|
before_update if: -> { parent_changed? || name_changed? } do
|
||||||
|
self[:pathname] = (parent ? parent.pathname + PATHNAME_DELIMITER : '') + self[:name]
|
||||||
|
end
|
||||||
|
|
||||||
|
after_update if: :pathname_previously_changed? do
|
||||||
quantities = Quantity.arel_table
|
quantities = Quantity.arel_table
|
||||||
selected = Arel::Table.new('selected')
|
selected = Arel::Table.new('selected')
|
||||||
|
|
||||||
# Add :name/:parent setters and update self :pathname there
|
|
||||||
Quantity.with_recursive(selected: [
|
Quantity.with_recursive(selected: [
|
||||||
quantities.project(quantities[:id].as('quantity_id'), quantities[:pathname])
|
quantities.project(quantities[:id].as('quantity_id'), quantities[:pathname])
|
||||||
.where(quantities[:id].eq(id)),
|
.where(quantities[:id].eq(id)),
|
||||||
quantities.project(
|
quantities.project(
|
||||||
quantities[:id],
|
quantities[:id],
|
||||||
selected[:pathname].concat(Arel::Nodes.build_quoted(' → '))
|
selected[:pathname].concat(Arel::Nodes.build_quoted(PATHNAME_DELIMITER))
|
||||||
.concat(quantities[:name])
|
.concat(quantities[:name])
|
||||||
).join(selected).on(selected[:quantity_id].eq(quantities[:parent_id]))
|
).join(selected).on(selected[:quantity_id].eq(quantities[:parent_id]))
|
||||||
]).joins(:selected).update_all(pathname: selected[:pathname])
|
]).joins(:selected).update_all(pathname: selected[:pathname])
|
||||||
end
|
end
|
||||||
|
|
||||||
def parent=(value)
|
|
||||||
super
|
|
||||||
self[:depth] = parent&.depth&.succ || 0
|
|
||||||
end
|
|
||||||
|
|
||||||
def parent_id=(value)
|
|
||||||
super
|
|
||||||
self[:depth] = parent&.depth&.succ || 0
|
|
||||||
end
|
|
||||||
|
|
||||||
scope :defaults, ->{ where(user: nil) }
|
scope :defaults, ->{ where(user: nil) }
|
||||||
|
|
||||||
# Return: ordered [sub]hierarchy
|
# Return: ordered [sub]hierarchy
|
||||||
|
Loading…
x
Reference in New Issue
Block a user