126 lines
4.4 KiB
Ruby
126 lines
4.4 KiB
Ruby
class ExternalWork < ApplicationRecord
|
|
include Bookmarkable
|
|
include Filterable
|
|
include Searchable
|
|
|
|
has_many :related_works, as: :parent
|
|
|
|
belongs_to :language
|
|
|
|
# .duplicate.count.size returns the number of URLs with multiple external works
|
|
scope :duplicate, -> { group(:url).having("count(DISTINCT id) > 1") }
|
|
|
|
scope :for_blurb, -> { includes(:language, :tags) }
|
|
|
|
AUTHOR_LENGTH_MAX = 500
|
|
|
|
validates_presence_of :title
|
|
validates_length_of :title, minimum: ArchiveConfig.TITLE_MIN,
|
|
too_short: ts("must be at least %{min} characters long.",
|
|
min: ArchiveConfig.TITLE_MIN)
|
|
validates_length_of :title, maximum: ArchiveConfig.TITLE_MAX,
|
|
too_long: ts("must be less than %{max} characters long.",
|
|
max: ArchiveConfig.TITLE_MAX)
|
|
|
|
validates_length_of :summary, allow_blank: true, maximum: ArchiveConfig.SUMMARY_MAX,
|
|
too_long: ts("must be less than %{max} characters long.",
|
|
max: ArchiveConfig.SUMMARY_MAX)
|
|
|
|
validates :author, presence: { message: ts("can't be blank") }
|
|
validates_length_of :author, maximum: AUTHOR_LENGTH_MAX,
|
|
too_long: ts("must be less than %{max} characters long.",
|
|
max: AUTHOR_LENGTH_MAX)
|
|
|
|
validates :user_defined_tags_count,
|
|
at_most: { maximum: proc { ArchiveConfig.USER_DEFINED_TAGS_MAX } }
|
|
|
|
# TODO: External works should have fandoms, but they currently don't get added through the
|
|
# post new work form so we can't validate them
|
|
#validates_presence_of :fandoms
|
|
|
|
before_validation :cleanup_url
|
|
# i18n-tasks-use t("errors.attributes.url.invalid")
|
|
validates :url, presence: true, url_format: true, url_active: true
|
|
def cleanup_url
|
|
self.url = Addressable::URI.heuristic_parse(self.url) if self.url
|
|
rescue Addressable::URI::InvalidURIError
|
|
# url_format validation creates the error message
|
|
end
|
|
|
|
# Allow encoded characters to display correctly in titles
|
|
def title
|
|
read_attribute(:title).try(:html_safe)
|
|
end
|
|
|
|
########################################################################
|
|
# VISIBILITY
|
|
########################################################################
|
|
# Adapted from work.rb
|
|
|
|
scope :visible_to_all, -> { where(hidden_by_admin: false) }
|
|
scope :visible_to_registered_user, -> { where(hidden_by_admin: false) }
|
|
scope :visible_to_admin, -> { where("") }
|
|
|
|
# a complicated dynamic scope here:
|
|
# if the user is an Admin, we use the "visible_to_admin" scope
|
|
# if the user is not a logged-in User, we use the "visible_to_all" scope
|
|
# otherwise, we use a join to get userids and then get all posted works that are either unhidden OR belong to this user.
|
|
# Note: in that last case we have to use select("DISTINCT works.") because of cases where the same user appears twice
|
|
# on a work.
|
|
scope :visible_to_user, lambda {|user| user.is_a?(Admin) ? visible_to_admin : visible_to_all}
|
|
|
|
# Use the current user to determine what external works are visible
|
|
scope :visible, -> { visible_to_user(User.current_user) }
|
|
|
|
# Visible unless we're hidden by admin, in which case only an Admin can see.
|
|
def visible?(user=User.current_user)
|
|
self.hidden_by_admin? ? user.kind_of?(Admin) : true
|
|
end
|
|
|
|
# Visibility has changed, which means we need to reindex
|
|
# the external work's bookmarker pseuds, to update their bookmark counts.
|
|
def should_reindex_pseuds?
|
|
pertinent_attributes = %w[id hidden_by_admin]
|
|
destroyed? || (saved_changes.keys & pertinent_attributes).present?
|
|
end
|
|
|
|
######################
|
|
# SEARCH
|
|
######################
|
|
|
|
def bookmarkable_json
|
|
as_json(
|
|
root: false,
|
|
only: [
|
|
:title, :summary, :hidden_by_admin, :created_at
|
|
],
|
|
methods: [
|
|
:posted, :restricted, :tag, :filter_ids, :rating_ids,
|
|
:archive_warning_ids, :category_ids, :fandom_ids, :character_ids,
|
|
:relationship_ids, :freeform_ids, :creators, :revised_at
|
|
]
|
|
).merge(
|
|
language_id: language&.short,
|
|
bookmarkable_type: "ExternalWork",
|
|
bookmarkable_join: { name: "bookmarkable" }
|
|
)
|
|
end
|
|
|
|
def posted
|
|
true
|
|
end
|
|
alias_method :posted?, :posted
|
|
|
|
def restricted
|
|
false
|
|
end
|
|
alias_method :restricted?, :restricted
|
|
|
|
def creators
|
|
[author]
|
|
end
|
|
|
|
def revised_at
|
|
created_at
|
|
end
|
|
end
|