Skip to content
Snippets Groups Projects
post.rb 6.78 KiB
Newer Older
Arnaud Levy's avatar
Arnaud Levy committed
# == Schema Information
#
# Table name: communication_website_posts
#
#  id                       :uuid             not null, primary key
Sébastien Gaya's avatar
Sébastien Gaya committed
#  featured_image_alt       :string
Arnaud Levy's avatar
Arnaud Levy committed
#  featured_image_credit    :text
Arnaud Levy's avatar
Arnaud Levy committed
#  github_path              :text
pabois's avatar
pabois committed
#  meta_description         :text
pabois's avatar
pabois committed
#  pinned                   :boolean          default(FALSE)
Arnaud Levy's avatar
Arnaud Levy committed
#  published                :boolean          default(FALSE)
#  published_at             :datetime
Arnaud Levy's avatar
Arnaud Levy committed
#  slug                     :text
#  summary                  :text
Sébastien Gaya's avatar
Sébastien Gaya committed
#  text                     :text
Arnaud Levy's avatar
Arnaud Levy committed
#  title                    :string
#  created_at               :datetime         not null
#  updated_at               :datetime         not null
pabois's avatar
pabois committed
#  author_id                :uuid             indexed
#  communication_website_id :uuid             not null, indexed
Sébastien Gaya's avatar
Sébastien Gaya committed
#  language_id              :uuid             not null, indexed
#  original_id              :uuid             indexed
pabois's avatar
pabois committed
#  university_id            :uuid             not null, indexed
Arnaud Levy's avatar
Arnaud Levy committed
#
# Indexes
#
pabois's avatar
pabois committed
#  index_communication_website_posts_on_author_id                 (author_id)
Arnaud Levy's avatar
Arnaud Levy committed
#  index_communication_website_posts_on_communication_website_id  (communication_website_id)
pabois's avatar
pabois committed
#  index_communication_website_posts_on_language_id               (language_id)
Sébastien Gaya's avatar
Sébastien Gaya committed
#  index_communication_website_posts_on_original_id               (original_id)
Arnaud Levy's avatar
Arnaud Levy committed
#  index_communication_website_posts_on_university_id             (university_id)
#
# Foreign Keys
#
pabois's avatar
pabois committed
#  fk_rails_1e0d058a25  (university_id => universities.id)
Sébastien Gaya's avatar
Sébastien Gaya committed
#  fk_rails_bbbef3b1e9  (original_id => communication_website_posts.id)
pabois's avatar
pabois committed
#  fk_rails_d1c1a10946  (communication_website_id => communication_websites.id)
#  fk_rails_e0eec447b0  (author_id => university_people.id)
Arnaud Levy's avatar
Arnaud Levy committed
#
class Communication::Website::Post < ApplicationRecord
pabois's avatar
pabois committed
  include Sanitizable
  include WithBlobs
Arnaud Levy's avatar
Arnaud Levy committed
  include WithBlocks
Arnaud Levy's avatar
Arnaud Levy committed
  include WithDuplication
  include WithFeaturedImage
  include WithGit
pabois's avatar
pabois committed
  include WithMenuItemTarget
Arnaud Levy's avatar
Arnaud Levy committed
  include WithPermalink
Sébastien Gaya's avatar
Sébastien Gaya committed
  include WithSlug # We override slug_unavailable? method
Sébastien Gaya's avatar
Sébastien Gaya committed
  include WithTranslations
Arnaud Levy's avatar
Arnaud Levy committed
  include WithUniversity
pabois's avatar
pabois committed

  has_summernote :text # TODO: Remove text attribute

pabois's avatar
pabois committed
  has_one :imported_post,
          class_name: 'Communication::Website::Imported::Post',
          dependent: :destroy
Arnaud Levy's avatar
Arnaud Levy committed
  belongs_to :website,
pabois's avatar
pabois committed
             class_name: 'Communication::Website',
Arnaud Levy's avatar
Arnaud Levy committed
             foreign_key: :communication_website_id
pabois's avatar
pabois committed
  belongs_to :author,
Sébastien Gaya's avatar
Sébastien Gaya committed
             class_name: 'University::Person',
pabois's avatar
pabois committed
             optional: true
pabois's avatar
pabois committed
  has_and_belongs_to_many :categories,
                          class_name: 'Communication::Website::Category',
                          join_table: 'communication_website_categories_posts',
                          foreign_key: 'communication_website_post_id',
                          association_foreign_key: 'communication_website_category_id'
Arnaud Levy's avatar
Arnaud Levy committed

  validates :title, presence: true

Arnaud Levy's avatar
Arnaud Levy committed
  before_validation :set_published_at
  after_save_commit :update_authors_statuses!, if: :saved_change_to_author_id?
  scope :published, -> {
    where("
      communication_website_posts.published = true AND
      DATE(communication_website_posts.published_at) <= now()
    ")
  }
  scope :published_in_the_future, -> {
    where("
      communication_website_posts.published = true AND
      DATE(communication_website_posts.published_at) > now()
    ")
  }
Sébastien Gaya's avatar
Sébastien Gaya committed
  scope :ordered, -> { order(pinned: :desc, published_at: :desc, created_at: :desc) }
  scope :recent, -> { order(published_at: :desc).limit(5) }
pabois's avatar
pabois committed
  scope :for_author, -> (author_id) { where(author_id: author_id) }
Sébastien Gaya's avatar
Sébastien Gaya committed
  scope :for_category, -> (category_id) { joins(:categories).where(communication_website_categories: { id: category_id }).distinct }
Sébastien Gaya's avatar
Sébastien Gaya committed
  scope :for_pinned, -> (pinned) { where(pinned: pinned == 'true') }
pabois's avatar
pabois committed
  scope :for_search_term, -> (term) {
    where("
pabois's avatar
pabois committed
      unaccent(communication_website_posts.meta_description) ILIKE unaccent(:term) OR
      unaccent(communication_website_posts.summary) ILIKE unaccent(:term) OR
pabois's avatar
pabois committed
      unaccent(communication_website_posts.text) ILIKE unaccent(:term) OR
      unaccent(communication_website_posts.title) ILIKE unaccent(:term)
    ", term: "%#{sanitize_sql_like(term)}%")
  }
Arnaud Levy's avatar
Arnaud Levy committed

Arnaud Levy's avatar
Arnaud Levy committed
    published && published_at && published_at.to_date <= Date.today
Arnaud Levy's avatar
Arnaud Levy committed
  # Is it used?
pabois's avatar
pabois committed
  def path
Arnaud Levy's avatar
Arnaud Levy committed
    # used in menu_item#static_target
Sébastien Gaya's avatar
Sébastien Gaya committed
    "/#{published_at.strftime "%Y/%m/%d"}/#{slug}"
pabois's avatar
pabois committed
  end

  def git_path(website)
    "#{git_path_content_prefix(website)}posts/#{static_path}.html" if website.id == communication_website_id && published && published_at
Arnaud Levy's avatar
Arnaud Levy committed
  end

Arnaud Levy's avatar
Arnaud Levy committed
  def static_path
Arnaud Levy's avatar
Arnaud Levy committed
    "#{published_at.year}/#{published_at.strftime "%Y-%m-%d"}-#{slug}"
Arnaud Levy's avatar
Arnaud Levy committed
  end

Arnaud Levy's avatar
Arnaud Levy committed
  def template_static
    "admin/communication/websites/posts/static"
  end

  def git_dependencies(website)
pabois's avatar
pabois committed
    dependencies = [self] + website.menus
Sébastien Gaya's avatar
Sébastien Gaya committed
    dependencies += categories
    dependencies += active_storage_blobs
    dependencies += git_block_dependencies
Sébastien Gaya's avatar
Sébastien Gaya committed
    dependencies += university.communication_blocks.where(template_kind: :posts).includes(:about).map(&:about).uniq
Sébastien Gaya's avatar
Sébastien Gaya committed
    if author.present?
Sébastien Gaya's avatar
Sébastien Gaya committed
      dependencies += [author, author.author, translated_author, translated_author.author]
Sébastien Gaya's avatar
Sébastien Gaya committed
      dependencies += author.active_storage_blobs
Sébastien Gaya's avatar
Sébastien Gaya committed
      dependencies += translated_author.active_storage_blobs
Sébastien Gaya's avatar
Sébastien Gaya committed
    end
    dependencies
Arnaud Levy's avatar
Arnaud Levy committed
  end

pabois's avatar
pabois committed
  def git_destroy_dependencies(website)
    [self] + explicit_active_storage_blobs
Arnaud Levy's avatar
Arnaud Levy committed
  end

Arnaud Levy's avatar
Arnaud Levy committed
  def url
    return unless published
    return if website.url.blank?
Arnaud Levy's avatar
Arnaud Levy committed
    return if website.special_page(Communication::Website::Page::CommunicationPost)&.path.blank?
    return if current_permalink_in_website(website).blank?
Sébastien Gaya's avatar
Sébastien Gaya committed
    "#{Static.remove_trailing_slash website.url}#{Static.clean_path current_permalink_in_website(website).path}"
Sébastien Gaya's avatar
Sébastien Gaya committed
  def translated_author
    @translated_author ||= author.find_or_translate!(language)
  end

Arnaud Levy's avatar
Arnaud Levy committed
  def to_s
    "#{title}"
  end

  protected

  def slug_unavailable?(slug)
Arnaud Levy's avatar
Arnaud Levy committed
    self.class.unscoped
Sébastien Gaya's avatar
Sébastien Gaya committed
              .where(communication_website_id: self.communication_website_id, language_id: language_id, slug: slug)
Arnaud Levy's avatar
Arnaud Levy committed
              .where.not(id: self.id)
              .exists?
Arnaud Levy's avatar
Arnaud Levy committed
    self.published_at = Time.zone.now if published && published_at.nil?

  def explicit_blob_ids
Sébastien Gaya's avatar
Sébastien Gaya committed
    super.concat [featured_image&.blob_id]
  end

  def inherited_blob_ids
    [best_featured_image&.blob_id]
  end

  def update_authors_statuses!
    old_author = University::Person.find_by(id: author_id_before_last_save)
    if old_author && old_author.communication_website_posts.none?
      old_author.update_and_sync(is_author: false)
    end
    author.update_and_sync(is_author: true) if author_id
  end
Sébastien Gaya's avatar
Sébastien Gaya committed

  def translate_additional_data!(translation)
    categories.each do |category|
Sébastien Gaya's avatar
Sébastien Gaya committed
      translated_category = category.find_or_translate!(translation.language)
      translation.categories << translated_category
    end
Sébastien Gaya's avatar
Sébastien Gaya committed
    translation.update(author_id: author.find_or_translate!(translation.language).id) if author_id.present?
Sébastien Gaya's avatar
Sébastien Gaya committed
  end
Arnaud Levy's avatar
Arnaud Levy committed
end