class Gift < ApplicationRecord NAME_LENGTH_MAX = 100 belongs_to :work, touch: true belongs_to :pseud has_one :user, through: :pseud validates_length_of :recipient_name, maximum: NAME_LENGTH_MAX, too_long: ts("must be less than %{max} characters long.", max: NAME_LENGTH_MAX), allow_blank: true validates_format_of :recipient_name, message: ts("must contain at least one letter or number."), with: /[a-zA-Z0-9]/, allow_blank: true validate :has_name_or_pseud def has_name_or_pseud unless self.pseud || !self.recipient_name.blank? errors.add(:base, ts("A gift must have a recipient specified.")) end end validates_uniqueness_of :pseud_id, scope: :work_id, message: ts("You can't give a gift to the same person twice.") # Don't allow giving the same gift to the same user more than once validate :has_not_given_to_user def has_not_given_to_user if self.pseud && self.work other_pseuds = Gift.where(work_id: self.work_id).pluck(:pseud_id) - [self.pseud_id] if Pseud.where(id: other_pseuds, user_id: self.pseud.user_id).exists? errors.add(:base, ts("You seem to already have given this work to that user.")) end end end scope :for_pseud, lambda {|pseud| where("pseud_id = ?", pseud.id)} scope :for_user, lambda {|user| where("pseud_id IN (?)", user.pseuds.collect(&:id).flatten)} scope :for_recipient_name, lambda {|name| where("recipient_name = ?", name)} scope :for_name_or_byline, lambda { |name| where("recipient_name = ? OR pseud_id = ?", name, Pseud.parse_byline(name)) } scope :in_collection, lambda {|collection| select("DISTINCT gifts.*"). joins({work: :collection_items}). where("collection_items.collection_id = ?", collection.id) } scope :name_only, -> { select(:recipient_name) } scope :include_pseuds, -> { includes(work: [:pseuds]) } scope :not_rejected, -> { where(rejected: false) } scope :are_rejected, -> { where(rejected: true) } def recipient=(new_recipient_name) self.pseud = Pseud.parse_byline(new_recipient_name) self.recipient_name = pseud ? nil : new_recipient_name end def recipient pseud ? pseud.byline : recipient_name end end