|
- class Post < ApplicationRecord
- require 'mini_magick'
-
- belongs_to :parent, class_name: 'Post', optional: true, foreign_key: 'parent_id'
- 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_one_attached :thumbnail
-
- before_validation :normalise_url
-
- validates :url, presence: true, uniqueness: true
-
- validate :validate_original_created_range
- validate :url_must_be_http_url
-
- 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 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
|