* add party_shares table and model with associations * add party share errors and blueprint * add party shares controller and routes * include shared parties in listings and show * add party share factory and model specs * add party shares controller specs * include shares in party response for owners * add crew shared_parties endpoint
115 lines
No EOL
3 KiB
Ruby
115 lines
No EOL
3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class User < ApplicationRecord
|
|
before_save { self.email = email.downcase }
|
|
|
|
##### ActiveRecord Associations
|
|
has_many :parties, dependent: :destroy
|
|
has_many :favorites, dependent: :destroy
|
|
has_many :collection_characters, dependent: :destroy
|
|
has_many :collection_weapons, dependent: :destroy
|
|
has_many :collection_summons, dependent: :destroy
|
|
has_many :collection_job_accessories, dependent: :destroy
|
|
has_many :collection_artifacts, dependent: :destroy
|
|
|
|
# Crew associations
|
|
has_many :crew_memberships, dependent: :destroy
|
|
has_one :active_crew_membership, -> { where(retired: false) }, class_name: 'CrewMembership'
|
|
has_one :crew, through: :active_crew_membership
|
|
has_many :crew_invitations, dependent: :destroy
|
|
has_many :pending_crew_invitations, -> { where(status: :pending) }, class_name: 'CrewInvitation'
|
|
has_many :sent_crew_invitations, class_name: 'CrewInvitation', foreign_key: :invited_by_id, dependent: :nullify
|
|
has_many :party_shares, foreign_key: :shared_by_id, dependent: :destroy
|
|
|
|
##### ActiveRecord Validations
|
|
validates :username,
|
|
presence: true,
|
|
length: { minimum: 3, maximum: 26 }
|
|
|
|
validates :email,
|
|
presence: true,
|
|
uniqueness: true,
|
|
email: true
|
|
|
|
validates :password,
|
|
length: { minimum: 8 },
|
|
presence: true,
|
|
on: :create
|
|
|
|
validates :password,
|
|
length: { minimum: 8 },
|
|
on: :update,
|
|
if: :password_digest_changed?
|
|
|
|
validates :password_confirmation,
|
|
presence: true,
|
|
on: :create
|
|
|
|
validates :password_confirmation,
|
|
presence: true,
|
|
on: :update,
|
|
if: :password_digest_changed?
|
|
|
|
##### ActiveModel Security
|
|
has_secure_password
|
|
|
|
##### Enums
|
|
# Enum for collection privacy levels (1-based to avoid JavaScript falsy 0 issues)
|
|
enum :collection_privacy, {
|
|
everyone: 1,
|
|
crew_only: 2,
|
|
private_collection: 3
|
|
}, prefix: true
|
|
|
|
##### Instance Methods
|
|
def favorite_parties
|
|
favorites.map(&:party)
|
|
end
|
|
|
|
def admin?
|
|
role == 9
|
|
end
|
|
|
|
def blueprint
|
|
UserBlueprint
|
|
end
|
|
|
|
# Check if collection is viewable by another user
|
|
def collection_viewable_by?(viewer)
|
|
return true if self == viewer # Owners can always view their own collection
|
|
|
|
case collection_privacy
|
|
when 'everyone'
|
|
true
|
|
when 'crew_only'
|
|
viewer.present? && in_same_crew_as?(viewer)
|
|
when 'private_collection'
|
|
false
|
|
else
|
|
false
|
|
end
|
|
end
|
|
|
|
# Check if user is in same crew as another user
|
|
def in_same_crew_as?(other_user)
|
|
return false unless other_user.present?
|
|
return false unless crew.present? && other_user.crew.present?
|
|
|
|
crew.id == other_user.crew.id
|
|
end
|
|
|
|
# Get the user's crew role
|
|
def crew_role
|
|
active_crew_membership&.role
|
|
end
|
|
|
|
# Check if user is a crew officer (captain or vice captain)
|
|
def crew_officer?
|
|
crew_role.in?(%w[captain vice_captain])
|
|
end
|
|
|
|
# Check if user is a crew captain
|
|
def crew_captain?
|
|
crew_role == 'captain'
|
|
end
|
|
end |