BigW Consortium Gitlab

route.rb 1.8 KB
Newer Older
1
class Route < ActiveRecord::Base
2
  belongs_to :source, polymorphic: true # rubocop:disable Cop/PolymorphicAssociations
3 4 5 6 7 8 9 10

  validates :source, presence: true

  validates :path,
    length: { within: 1..255 },
    presence: true,
    uniqueness: { case_sensitive: false }

11 12
  after_create :delete_conflicting_redirects
  after_update :delete_conflicting_redirects, if: :path_changed?
13
  after_update :create_redirect_for_old_path
14
  after_update :rename_descendants
15

16 17
  scope :inside_path, -> (path) { where('routes.path LIKE ?', "#{sanitize_sql_like(path)}/%") }

18
  def rename_descendants
Michael Kozono committed
19
    return unless path_changed? || name_changed?
20

21
    descendant_routes = self.class.inside_path(path_was)
22

23
    descendant_routes.each do |route|
Michael Kozono committed
24
      attributes = {}
25

Michael Kozono committed
26 27 28
      if path_changed? && route.path.present?
        attributes[:path] = route.path.sub(path_was, path)
      end
29

Michael Kozono committed
30 31
      if name_changed? && name_was.present? && route.name.present?
        attributes[:name] = route.name.sub(name_was, name)
32
      end
Michael Kozono committed
33

34 35 36 37
      if attributes.present?
        old_path = route.path

        # Callbacks must be run manually
38
        route.update_columns(attributes.merge(updated_at: Time.now))
39 40 41 42 43 44

        # We are not calling route.delete_conflicting_redirects here, in hopes
        # of avoiding deadlocks. The parent (self, in this method) already
        # called it, which deletes conflicts for all descendants.
        route.create_redirect(old_path) if attributes[:path]
      end
45 46
    end
  end
47

48 49 50 51 52 53 54 55 56 57
  def delete_conflicting_redirects
    conflicting_redirects.delete_all
  end

  def conflicting_redirects
    RedirectRoute.matching_path_and_descendants(path)
  end

  def create_redirect(path)
    RedirectRoute.create(source: source, path: path)
58
  end
Michael Kozono committed
59 60 61 62 63 64

  private

  def create_redirect_for_old_path
    create_redirect(path_was) if path_changed?
  end
65
end