Created
June 25, 2021 12:28
-
-
Save masasakano/f2dae1c6bedae430da4f9ae3f3277727 to your computer and use it in GitHub Desktop.
Ruby-on-Rails model helper methods to get dependent children of a record, maybe only those that are not cascade-destroyed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| module ApplicationHelper | |
| # to check whether a record has any dependent children | |
| # | |
| # @see https://stackoverflow.com/a/68129947/3577922 | |
| # | |
| def has_children? | |
| ## This would be simpler though may initiate more SQL calls: | |
| # self.class.reflect_on_all_associations.map{ |a| self.send(a.name).any? }.any? | |
| self.class.reflect_on_all_associations.each{ |a| return true if self.send(a.name).any? } | |
| false | |
| end | |
| # to check whether a record has any dependent children that | |
| # would not be cascade-destroyed. | |
| # | |
| # @see has_children? | |
| # @see undestroyable_associations | |
| # | |
| # @param skip_nullify: [Boolean] if true (Def), "dependent: :nullify" | |
| # will be treated the same as ":destroy", namely they are not counted as "undestroyable". | |
| def has_undestroyable_children?(**kwd) | |
| undestroyable_associations(**kwd).each{ |a| return true if self.send(a.name).any? } | |
| false | |
| end | |
| # Returns all undestroyable children | |
| # | |
| # @see undestroyable_associations | |
| # | |
| # @return [Array<ApplicationRecord>] | |
| def undestroyable_children(**kwd) | |
| undestroyable_associations(**kwd).map{ |a| self.send(a.name) }.flatten | |
| false | |
| end | |
| # Returns an Array of associations that may contain dependent children that | |
| # would not be cascade-destroyed. | |
| # | |
| # For example, a user alywas has a role, the association record of which | |
| # would be destroyed as soon as the user is removed from the DB. | |
| # That is normal and needs no caution. | |
| # By contrast, if a user owns an article that would not be cascade-destroyed, | |
| # deleting of the user must be treated with caution. | |
| # | |
| # This method returns the associations that fall into the latter. | |
| # | |
| # @see has_undestroyable_children? | |
| # | |
| # @param skip_nullify: [Boolean] if true (Def), "dependent: :nullify" | |
| # will be treated the same as ":destroy", namely they are not counted as "undestroyable". | |
| # @return [Array<ActiveRecord::Reflection>] | |
| def undestroyable_associations(skip_nullify: true) | |
| destroy_keys = %i(destroy delete destroy_async) | |
| destroy_keys.push(:nullify) if skip_nullify | |
| # Note: the other potentials: [:restrict_with_exception, :restrict_with_error] | |
| self.class.reflect_on_all_associations.filter{|i| | |
| opts = i.options | |
| (!(opts.has_key?(:through) && opts[:through]) && | |
| !(opts.has_key?(:dependent) && destroy_keys.include?(opts[:dependent]))) | |
| } | |
| end | |
| private :undestroyable_associations | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment