class User < ActiveRecord::Base include PrettyParam DefaultAuthServerId = 1 PreviewTopContributorsCount = 3 has_many :closet_hangers has_many :closet_lists has_many :closeted_items, through: :closet_hangers, source: :item has_many :owned_items, -> { where(ClosetHanger.arel_table[:owned].eq(true)) }, through: :closet_hangers, source: :item has_many :wanted_items, -> { where(ClosetHanger.arel_table[:owned].eq(false)) }, through: :closet_hangers, source: :item has_many :contributions has_many :neopets_connections has_many :outfits belongs_to :contact_neopets_connection, class_name: 'NeopetsConnection' scope :top_contributors, -> { order('points DESC').where('points > 0') } devise :rememberable attr_accessible :owned_closet_hangers_visibility, :wanted_closet_hangers_visibility, :contact_neopets_connection_id def admin? name == 'matchu' # you know that's right. end def contribute!(pet) new_contributions = [] pet.contributables.each do |contributable| if contributable.new_record? contribution = Contribution.new contribution.contributed = contributable contribution.user = self new_contributions << contribution end end new_points = 0 # temp assignment for scoping Pet.transaction do pet.save! new_contributions.each do |contribution| Rails.logger.debug("Saving contribution of #{contribution.contributed.inspect}: #{contribution.contributed_type.inspect}, #{contribution.contributed_id.inspect}") begin contribution.save! rescue ActiveRecord::RecordNotSaved => e raise ActiveRecord::RecordNotSaved, "#{e.message}, #{contribution.inspect}, #{contribution.valid?.inspect}, #{contribution.errors.inspect}" end end new_points = new_contributions.map(&:point_value).inject(0, &:+) self.points += new_points begin save! rescue ActiveRecord::RecordNotSaved => e raise ActiveRecord::RecordNotSaved, "#{e.message}, #{self.inspect}, #{self.valid?.inspect}, #{self.errors.inspect}" end end new_points end def assign_closeted_to_items!(items) # Assigning these items to a hash by ID means that we don't have to go # N^2 searching the items list for items that match the given IDs or vice # versa, and everything stays a lovely O(n) items_by_id = items.group_by(&:id) closet_hangers.where(:item_id => items_by_id.keys).each do |hanger| items = items_by_id[hanger.item_id] items.each do |item| if hanger.owned? item.owned = true else item.wanted = true end end end end def closet_hangers_groups_visible_to(user) if user == self [true, false] else public_closet_hangers_groups end end def public_closet_hangers_groups [].tap do |groups| groups << true if owned_closet_hangers_visibility >= ClosetVisibility[:public].id groups << false if wanted_closet_hangers_visibility >= ClosetVisibility[:public].id end end def null_closet_list(owned) owned ? null_owned_list : null_wanted_list end def null_owned_list ClosetList::NullOwned.new(self) end def null_wanted_list ClosetList::NullWanted.new(self) end def find_closet_list_by_id_or_null_owned(id_or_owned) id_or_owned_str = id_or_owned.to_s if id_or_owned_str == 'true' null_owned_list elsif id_or_owned_str == 'false' null_wanted_list else self.closet_lists.find id_or_owned end end def neopets_usernames neopets_connections.map(&:neopets_username) end def contact_neopets_username? contact_neopets_connection.present? end def contact_neopets_username contact_neopets_connection.try(:neopets_username) end def self.find_or_create_from_remote_auth_data(user_data) user = find_or_initialize_by_remote_id_and_auth_server_id( user_data['id'], DefaultAuthServerId ) if user.new_record? user.name = user_data['name'] user.save end user end def self.points_required_to_pass_top_contributor(offset) user = User.top_contributors.select(:points).limit(1).offset(offset).first user ? user.points : 0 end end