module Locomotive module Concerns module Site module AccessPoints extend ActiveSupport::Concern included do ## fields ## field :handle field :domains, type: Array, default: [] field :redirect_to_first_domain, type: Boolean, default: false ## indexes ## index domains: 1 ## validations ## validates_presence_of :handle validates_uniqueness_of :handle validates_exclusion_of :handle, in: Locomotive.config.reserved_site_handles validates_format_of :handle, with: Locomotive::Regexps::HANDLE, allow_blank: true, multiline: true validate :domains_must_be_valid_and_unique ## callbacks ## before_validation :prepare_domain_sync after_save :emit_domain_sync_event after_destroy :emit_domain_deletion_event ## named scopes ## scope :match_domain, ->(domain) { any_in(domains: [*domain]) } scope :match_domain_with_exclusion_of, ->(domain, site) { any_in(domains: [*domain]).where(:_id.ne => site.id) } end def to_param self.handle.to_s end def main_domain domains.first end def handle=(handle) super(handle.try(:downcase)) end def domains=(array) array.reject!(&:blank?) array = [] if array.blank?; super(array.map(&:downcase)) end protected def prepare_domain_sync previous_domains = self.domains_was || [] @added_domains = self.domains - previous_domains @removed_domains = previous_domains - self.domains end def domains_must_be_valid_and_unique return if self.domains.empty? self.domains.each do |domain| if self.class.match_domain_with_exclusion_of(domain, self).any? self.errors.add(:domains, :domain_taken, value: domain) end if not domain =~ Locomotive::Regexps::DOMAIN self.errors.add(:domains, :invalid_domain, value: domain) end end end def emit_domain_sync_event return if @added_domains.blank? && @removed_domains.blank? ActiveSupport::Notifications.instrument 'locomotive.site.domain_sync', { added: @added_domains, removed: @removed_domains } end def emit_domain_deletion_event return if self.domains.empty? ActiveSupport::Notifications.instrument 'locomotive.site.domain_sync', { removed: self.domains } end end end end end