# frozen_string_literal: true class Photo < ApplicationRecord include Likeable include Ownable include SearchPhotos PHOTO_CAPABLE = %w(Garden Planting Harvest Seed Post Crop).freeze has_many :photo_associations, dependent: :delete_all, inverse_of: :photo has_many :comments, as: :commentable, dependent: :destroy # This doesn't work, ActiveRecord tries to use the polymoriphic photographable # relationship instead. # has_many :crops, through: :photo_associations, counter_cache: true def crops Crop.distinct.joins(:photo_associations).where(photo_associations: { photo: self }) end validates :fullsize_url, url: true, presence: true validates :thumbnail_url, url: true, presence: true validates :link_url, url: true, presence: true validates :owner, presence: true validates :title, presence: true validates :license_name, presence: true # Should assert this is one of CC-BY, CC-BY-NC, etc validates :license_url, url: true, allow_blank: true # creates a relationship for each assignee type PHOTO_CAPABLE.each do |type| has_many type.downcase.pluralize.to_s.to_sym, through: :photo_associations, source: :photographable, source_type: type end scope :by_crop, ->(crop) { joins(:photo_associations).where(photo_associations: { crop: }) } scope :by_model, lambda { |model_name| joins(:photo_associations).where(photo_associations: { photographable_type: model_name.to_s }) } delegate :login_name, :slug, to: :owner, prefix: true # This is split into a side-effect free method and a side-effecting method # for easier stubbing and testing. def flickr_metadata flickr = owner.flickr info = flickr.photos.getInfo(photo_id: source_id) licenses = flickr.photos.licenses.getInfo license = licenses.find { |l| l.id.to_i == info.license.to_i } Rails.logger.error("Cannot find license: #{[info.license, licenses].inspect}") unless license { title: calculate_title(info), license_name: license.name, license_url: license.url, thumbnail_url: FlickRaw.url_q(info), fullsize_url: FlickRaw.url_z(info), link_url: FlickRaw.url_photopage(info), date_taken: info.dates.taken } end def associations? photo_associations.size.positive? end def destroy_if_unused destroy unless associations? end def calculate_title(info) if id && title # already has a title saved title elsif info.title # use title from flickr info.title else 'untitled' end end def set_flickr_metadata! update(flickr_metadata) end def to_s "#{title} by #{owner.login_name}" end def subject title end def author owner end def flickr_photo_id source_id if source == 'flickr' end end