* Extracting cross-model uniqueness validator Prior to this commit, we had somewhat duplicated logic across four models. In adding this validator we're consolidating the logic and tidying up each of the other models; letting the validator know which models are part of the "uniqueness gang." * Adding conditional test for validator * Bump for travis * Apply suggestions from code review Co-authored-by: Michael Kohl <citizen428@forem.com> Co-authored-by: Michael Kohl <citizen428@forem.com>
65 lines
1.8 KiB
Ruby
65 lines
1.8 KiB
Ruby
class Page < ApplicationRecord
|
|
TEMPLATE_OPTIONS = %w[contained full_within_layout json].freeze
|
|
|
|
validates :title, presence: true
|
|
validates :description, presence: true
|
|
validates :slug, presence: true, format: /\A[0-9a-z\-_]*\z/
|
|
validates :template, inclusion: { in: TEMPLATE_OPTIONS }
|
|
validate :body_present
|
|
validates :slug, unique_cross_model_slug: true, if: :slug_changed?
|
|
|
|
before_validation :set_default_template
|
|
before_save :evaluate_markdown
|
|
|
|
after_commit :ensure_uniqueness_of_landinge_page
|
|
after_commit :bust_cache
|
|
|
|
mount_uploader :social_image, ProfileImageUploader
|
|
resourcify
|
|
|
|
def self.landing_page
|
|
find_by(landing_page: true)
|
|
end
|
|
|
|
def path
|
|
is_top_level_path ? "/#{slug}" : "/page/#{slug}"
|
|
end
|
|
|
|
def feature_flag_name
|
|
"page_#{slug}"
|
|
end
|
|
|
|
private
|
|
|
|
def evaluate_markdown
|
|
if body_markdown.present?
|
|
parsed_markdown = MarkdownProcessor::Parser.new(body_markdown)
|
|
self.processed_html = parsed_markdown.finalize
|
|
else
|
|
self.processed_html = body_html
|
|
end
|
|
end
|
|
|
|
def set_default_template
|
|
self.template = "contained" if template.blank?
|
|
end
|
|
|
|
def body_present
|
|
return unless body_markdown.blank? && body_html.blank? && body_json.blank?
|
|
|
|
errors.add(:body_markdown, "must exist if body_html or body_json doesn't exist.")
|
|
end
|
|
|
|
# As there can only be one global landing page, we want to ensure that
|
|
# data integrity is preserved by setting `landing_page` to `false` for all
|
|
# other pages if the current one was transformed into a landing page
|
|
def ensure_uniqueness_of_landinge_page
|
|
return unless previous_changes["landing_page"] == [false, true]
|
|
|
|
Page.where.not(id: id).update_all(landing_page: false)
|
|
end
|
|
|
|
def bust_cache
|
|
Pages::BustCacheWorker.perform_async(slug)
|
|
end
|
|
end
|