socialforge/app/models/principal.rb

146 lines
5.4 KiB
Ruby
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Redmine - project management software
# Copyright (C) 2006-2013 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class Principal < ActiveRecord::Base
self.table_name = "#{table_name_prefix}users#{table_name_suffix}"
# Account statuses
# 0 全部1 活动的; 2 已注册; 3 锁定
STATUS_ANONYMOUS = 0
STATUS_ACTIVE = 1
STATUS_REGISTERED = 2
STATUS_LOCKED = 3
has_many :members, :foreign_key => 'user_id', :dependent => :destroy
has_many :memberships, :class_name => 'Member', :foreign_key => 'user_id', :include => [ :project, :roles ], :conditions => "#{Project.table_name}.status<>#{Project::STATUS_ARCHIVED}", :order => "#{Project.table_name}.name"
has_many :coursememberships, :class_name => 'Member', :foreign_key => 'user_id', :include => [ :course, :roles ], :conditions => "#{Course.table_name}.status<>#{Course::STATUS_ARCHIVED}", :order => "#{Course.table_name}.name"
has_many :projects, :through => :memberships
#add by nwb
has_many :courses, :through => :coursememberships
has_many :course_groups, :through => :members
has_many :issue_categories, :foreign_key => 'assigned_to_id', :dependent => :nullify
# Groups and active users
scope :active, lambda { where(:status => STATUS_ACTIVE) }
scope :like, lambda {|q|
q = q.to_s
if q.blank?
where({})
else
pattern = "%#{q}%".gsub("/","//").gsub("_","/_")
# sql = %w(login firstname lastname mail).map {|column| "LOWER(#{table_name}.#{column}) LIKE LOWER(:p)"}.join(" OR ")
sql= "LOWER(concat(lastname,firstname)) LIKE LOWER(:p) escape '/' or LOWER(login) LIKE LOWER(:p) escape '/' or LOWER(mail) LIKE LOWER(:p) escape '/'"
params = {:p => pattern}
if q =~ /^(.+)\s+(.+)$/
a, b = "#{$1}%", "#{$2}%"
sql << " OR (LOWER(#{table_name}.firstname) LIKE LOWER(:a) AND LOWER(#{table_name}.lastname) LIKE LOWER(:b))"
sql << " OR (LOWER(#{table_name}.firstname) LIKE LOWER(:b) AND LOWER(#{table_name}.lastname) LIKE LOWER(:a))"
params.merge!(:a => a, :b => b)
end
where(sql, params)
end
}
# Principals that are members of a collection of projects
scope :member_of, lambda {|projects|
projects = [projects] unless projects.is_a?(Array)
if projects.empty?
where("1=0")
else
ids = projects.map(&:id)
active.uniq.joins(:members).where("#{Member.table_name}.project_id IN (?)", ids)
end
}
# Principals that are not members of projects
scope :not_member_of, lambda {|projects|
projects = [projects] unless projects.is_a?(Array)
if projects.empty?
where("1=0")
else
ids = projects.map(&:id)
where("#{Principal.table_name}.id NOT IN (SELECT DISTINCT user_id FROM #{Member.table_name} WHERE project_id IN (?))", ids)
end
}
scope :not_member_of_course, lambda {|courses|
courses = [courses] unless courses.is_a?(Array)
if courses.empty?
where("1=0")
else
ids = courses.map(&:id)
where("#{Principal.table_name}.id NOT IN (SELECT DISTINCT user_id FROM #{Member.table_name} WHERE course_id IN (?))", ids)
end
}
scope :not_member_of_org, lambda {|org|
orgs = [org] unless org.is_a?(Array)
if orgs.empty?
where("1=0")
else
ids = orgs.map(&:id)
where("#{Principal.table_name}.id NOT IN (SELECT DISTINCT user_id FROM #{OrgMember.table_name} WHERE organization_id IN (?))", ids)
end
}
scope :sorted, lambda { order(*Principal.fields_for_order_statement)}
scope :applied_members, lambda {|project|
id = project.id
ids1 = project.applied_projects.map(&:user_id)
where("#{Principal.table_name}.id IN (SELECT DISTINCT user_id FROM #{Member.table_name} WHERE user_id in (?))", ids1)
}
before_create :set_default_empty_values
def name(formatter = nil)
to_s
end
def <=>(principal)
if principal.nil?
-1
elsif self.class.name == principal.class.name
self.to_s.downcase <=> principal.to_s.downcase
else
# groups after users
principal.class.name <=> self.class.name
end
end
# Returns an array of fields names than can be used to make an order statement for principals.
# Users are sorted before Groups.
# Examples:
def self.fields_for_order_statement(table=nil)
table ||= table_name
columns = ['type DESC'] + (User.name_formatter[:order] - ['id']) + ['lastname', 'id']
columns.uniq.map {|field| "#{table}.#{field}"}
end
protected
# Make sure we don't try to insert NULL values (see #4632)
def set_default_empty_values
self.login ||= ''
self.hashed_password ||= ''
self.firstname ||= ''
self.lastname ||= ''
self.mail ||= ''
true
end
end