module JamRuby class InvitedUser < ActiveRecord::Base include HtmlSanitize html_sanitize strict: [:note] VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i attr_accessible :email, :sender_id, :autofriend, :note, as: :admin attr_accessor :accepted_twice self.primary_key = 'id' ### Who sent this invitatio? # either admin_sender or user_sender is not null. If an administrator sends the invitation, then belongs_to :sender , :inverse_of => :invited_users, :class_name => "JamRuby::User", :foreign_key => "sender_id" belongs_to :receiver, :inverse_of => :receiver_users, :class_name => "JamRuby::User", :foreign_key => "receiver_id" # who is the invitation sent to? validates :email, format: {with: VALID_EMAIL_REGEX}, :if => lambda { |iu| iu.email_required? } validates :autofriend, :inclusion => {:in => [nil, true, false]} validates :invitation_code, :presence => true validates :note, length: {maximum: 1000}, no_profanity: true # 1000 == arbitrary. validate :one_facebook_invite_per_user, :if => lambda { |iu| iu.facebook_invite? } validate :valid_personalized_invitation # validate :not_accepted_twice validate :not_accepted_twice, :if => lambda { |iu| iu.email_required? } validate :can_invite? after_save :track_user_progression # ensure invitation code is always created before_validation(:on => :create) do self.invitation_code = SecureRandom.urlsafe_base64 if self.invitation_code.nil? self.sender_id = nil if self.sender_id.blank? # this coercion was done just to make activeadmin work self.receiver = User.find_by_email(self.email) unless self.email.nil? end FB_MEDIUM = 'facebook' def self.facebook_invite(user) where(:sender_id => user.id, :invite_medium => FB_MEDIUM).limit(1).first end def track_user_progression self.sender.update_progression_field(:first_invited_at) unless self.sender.nil? end def self.index(user) return InvitedUser.where(:sender_id => user).order(:updated_at) end def sender_display_name return sender.name end def accept! if self.accepted accepted_twice = true end self.accepted = true end def invited_by_administrator? sender.nil? || sender.admin # a nil sender can only be created by someone using jam-admin end def generate_signup_url url = "#{APP_CONFIG.external_root_url}/signup?invitation_code=#{self.invitation_code}" if APP_CONFIG.external_hostname == 'localhost' # the feed widget in facebook will not accept localhost. external_host name should be localhost only in dev environments url["localhost"] = "127.0.0.1" end url end def facebook_invite? FB_MEDIUM == self.invite_medium end def email_required? !self.facebook_invite? end def has_required_email? self.email.present? && self.email_required? end private def can_invite? errors.add(:sender, "can not invite others") if !invited_by_administrator? && !sender.can_invite? end def valid_personalized_invitation errors.add(:autofriend, "must be true if sender is specified") if autofriend && sender.nil? end def not_accepted_twice errors.add(:accepted, "you can only accept an invitation once") if accepted_twice end def one_facebook_invite_per_user rel = InvitedUser.where(:invite_medium => FB_MEDIUM, :sender_id => self.sender_id) rel = rel.where(['id != ?',self.id]) if self.id errors.add(:invite_medium, "one facebook invite allowed per user") if 0 < rel.count end end end