e03cc01109
#171 #171 #171 #171 #171 #171 #171 Co-authored-by: miteruzo <miteruzo@naver.com> Reviewed-on: #345
130 lines
3.6 KiB
Ruby
130 lines
3.6 KiB
Ruby
class Post < ApplicationRecord
|
|
require 'mini_magick'
|
|
|
|
belongs_to :uploaded_user, class_name: 'User', optional: true
|
|
|
|
has_many :post_tags, dependent: :destroy, inverse_of: :post
|
|
has_many :active_post_tags, -> { kept }, class_name: 'PostTag', inverse_of: :post
|
|
has_many :post_tags_with_discarded, -> { with_discarded }, class_name: 'PostTag'
|
|
has_many :tags, through: :active_post_tags
|
|
|
|
has_many :user_post_views, dependent: :delete_all
|
|
has_many :post_similarities, dependent: :delete_all
|
|
has_many :post_versions
|
|
|
|
has_many :parent_post_implications,
|
|
class_name: 'PostImplication',
|
|
foreign_key: :post_id,
|
|
dependent: :destroy,
|
|
inverse_of: :post
|
|
has_many :parents, through: :parent_post_implications, source: :parent_post
|
|
|
|
has_many :child_post_implications,
|
|
class_name: 'PostImplication',
|
|
foreign_key: :parent_post_id,
|
|
dependent: :destroy,
|
|
inverse_of: :parent_post
|
|
has_many :children, through: :child_post_implications, source: :post
|
|
|
|
has_one_attached :thumbnail
|
|
|
|
attribute :version_no, :integer, default: 1
|
|
|
|
before_validation :normalise_url
|
|
|
|
validates :url, presence: true, uniqueness: true
|
|
|
|
validate :validate_original_created_range
|
|
validate :url_must_be_http_url
|
|
|
|
def parent_posts = parents
|
|
|
|
def child_posts = children
|
|
|
|
def sibling_posts
|
|
parent_post_ids = parent_posts.order(:id).pluck(:id)
|
|
|
|
parent_post_ids.to_h { [_1, PostImplication.where(parent_post: _1).map(&:post)] }
|
|
end
|
|
|
|
def as_json options = { }
|
|
super(options).merge(thumbnail: thumbnail.attached? ?
|
|
Rails.application.routes.url_helpers.rails_blob_url(
|
|
thumbnail, only_path: false) :
|
|
nil)
|
|
rescue
|
|
super(options).merge(thumbnail: nil)
|
|
end
|
|
|
|
def snapshot_tag_names = tags.joins(:tag_name).order('tag_names.name').pluck('tag_names.name')
|
|
|
|
def snapshot_parent_post_ids = parents.order(:id).pluck(:id)
|
|
|
|
def related limit: nil
|
|
ids = post_similarities.order(cos: :desc)
|
|
ids = ids.limit(limit) if limit
|
|
ids = ids.pluck(:target_post_id)
|
|
return Post.none if ids.empty?
|
|
|
|
Post.where(id: ids)
|
|
.with_attached_thumbnail
|
|
.order(Arel.sql("FIELD(posts.id, #{ ids.join(',') })"))
|
|
end
|
|
|
|
def resized_thumbnail!
|
|
return unless thumbnail.attached?
|
|
|
|
image = MiniMagick::Image.read(thumbnail.download)
|
|
image.resize '180x180'
|
|
thumbnail.purge
|
|
thumbnail.attach(io: File.open(image.path),
|
|
filename: 'resized_thumbnail.jpg',
|
|
content_type: 'image/jpeg')
|
|
end
|
|
|
|
private
|
|
|
|
def validate_original_created_range
|
|
f = original_created_from
|
|
b = original_created_before
|
|
return if f.blank? || b.blank?
|
|
|
|
f = Time.zone.parse(f) if String === f
|
|
b = Time.zone.parse(b) if String === b
|
|
return if !(f) || !(b)
|
|
|
|
if f >= b
|
|
errors.add :original_created_before, 'オリジナルの作成日時の順番がをかしぃです.'
|
|
end
|
|
end
|
|
|
|
def url_must_be_http_url
|
|
begin
|
|
u = URI.parse(url)
|
|
rescue URI::InvalidURIError
|
|
errors.add(:url, 'URL が不正です.')
|
|
return
|
|
end
|
|
|
|
if !(u in URI::HTTP) || u.host.blank?
|
|
errors.add(:url, 'URL が不正です.')
|
|
return
|
|
end
|
|
end
|
|
|
|
def normalise_url
|
|
return if url.blank?
|
|
|
|
self.url = url.strip
|
|
|
|
u = URI.parse(url)
|
|
return unless u in URI::HTTP
|
|
|
|
u.host = u.host.downcase if u.host
|
|
u.path = u.path.sub(/\/\Z/, '') if u.path.present?
|
|
self.url = u.to_s
|
|
rescue URI::InvalidURIError
|
|
;
|
|
end
|
|
end
|