impress/app/models/user.rb

71 lines
2.2 KiB
Ruby

class User < ActiveRecord::Base
DefaultAuthServerId = 1
PreviewTopContributorsCount = 3
has_many :closet_hangers
has_many :closeted_items, :through => :closet_hangers, :source => :item
has_many :contributions
has_many :outfits
scope :top_contributors, order('points DESC').where(arel_table[:points].gt(0))
devise :rememberable
def contribute!(pet)
new_contributions = []
new_points = 0
pet.contributables.each do |contributable|
if contributable.new_record?
contribution = Contribution.new(:contributed => contributable,
:user => self)
new_contributions << contribution
new_points += contribution.point_value
end
end
self.points += new_points
Pet.transaction do
pet.save!
new_contributions.each do |contribution|
begin
contribution.save!
rescue ActiveRecord::RecordNotSaved => e
raise ActiveRecord::RecordNotSaved, "#{e.message}, #{contribution.inspect}, #{contribution.valid?.inspect}, #{contribution.errors.inspect}"
end
end
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.each { |item| items_by_id[item.id] = item }
closeted_item_ids = closeted_items.where(:id => items_by_id.keys).map(&:id)
closeted_item_ids.each { |id| items_by_id[id].closeted = true }
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