igmarin
6/24/2014 - 5:14 PM

User class with RoleModel, Omniauth & Gravatar

User class with RoleModel, Omniauth & Gravatar

require 'role_model'
require 'digest/md5'

class User < ActiveRecord::Base
  include RoleModel
  extend FriendlyId
  attr_accessible :email, :remember_me, :city_id, :username, :roles, :login, :user_profile_attributes, :contact_links_attributes, :password, :password_confirmation
  friendly_id :username, use: :slugged
  attr_accessor :login

  before_destroy :unsubscribe_from_mailchimp

  ROLES = %w[participant representative admin superadmin]
  roles :participant, :representative, :admin, :superadmin
  roles_attribute :roles_mask

  default_scope order(:username)

  ROLES.each do |name|
    scope name.pluralize.to_sym, where("roles_mask = ?", User.mask_for(name.to_sym))
  end

  scope :created_today, where("created_at >= ?", Time.zone.now.beginning_of_day)

  devise  :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable,
    :validatable, :confirmable, :invitable, :omniauthable

  belongs_to  :city
  has_one     :user_profile, dependent: :destroy
  has_many    :contact_links, dependent: :destroy
  has_many    :city_votes, dependent: :delete_all
  has_many    :city_followers, dependent: :delete_all
  has_many    :requests
  has_many    :approvals
  has_many    :events
  has_many    :following_cities, through: :city_followers, source: :city
  accepts_nested_attributes_for :contact_links, :user_profile, allow_destroy: true

  validates :username, uniqueness: { case_sensitive: false }, presence: true

  def display_name
    user_profile.try(:name) || username || email
  end

  def is? role
    roles.include? role
  end

  def follow_city city
    self.following_cities << city
  end

  def unfollow_city city
    self.following_cities.delete(city)
  end

  def superadmin_or_admin_for_city(given_city)
    is? :superadmin or (is? :admin and city == given_city)
  end

  def self.find_first_by_auth_conditions(warden_conditions)
    conditions = warden_conditions.dup
    if login = conditions.delete(:login)
      where(conditions).where(["lower(username) = :value OR lower(email) = :value", {value: login.downcase}]).first
    else
      where(conditions).first
    end
  end

  def avatar
    user_profile.try(:avatar) || "http://www.gravatar.com/avatar/#{Digest::MD5::hexdigest(self.email).downcase}"
  end

  def to_s
    {email: {email: email}}
  end

  def self.process_omniauth(auth)
    where(auth.slice(:provider, :uid)).first_or_create do |user|
      user.provider = auth.provider
      user.uid      = auth.uid
      user.username = auth.info.nickname
      user.email    = auth.info.email if auth.info.email
      user.build_user_profile(name: auth.info.name, bio: auth.info.description ? auth.info.description : "", avatar: auth.info.image)
      user.contact_links.build(network: auth.provider, network_url: auth.info.nickname)
      user.skip_confirmation!
    end
  end

  def self.new_with_session(params, session)
    if session["devise.user_attributes"]
      new(session["devise.user_attributes"],
          without_protection: true) do |user|
        user.attributes = params
        user.valid?
      end
    else
      super
    end
  end

  def update_with_password(params, *options)
    if encrypted_password.blank? && provider.present?
      update_attributes(params, *options)
    else
      super
    end
  end

  def password_required?
    super && provider.blank?
  end

  def email_required?
    super && provider.blank?
  end

  private
  def unsubscribe_from_mailchimp
    MailchimpSubscription.unsubscribe_from_list(self.email)
  end
end