简单的分析一下,发觉有了文档什么问题都不是问题!
model代码中我发觉user.rb代码比较丰富多彩一些,那就拿user.rb拿分析一下.
ruby 代码
model代码中我发觉user.rb代码比较丰富多彩一些,那就拿user.rb拿分析一下.
ruby 代码
- require 'digest/sha1' #分析:引入Hash加密算法
- class User < ActiveRecord::Base
- has_many :moderatorships, :dependent => :destroy
- has_many :forums, :through => :moderatorships, :order => 'forums.name'
- has_many :posts
- has_many :topics
- has_many :monitorships
- has_many :monitored_topics, :through => :monitorships, :conditions => ['monitorships.active = ?', true], :order => 'topics.replied_at desc', :source => :topic
- #分析:
- #has_many就是表与表之间一对多的关系,就如:users表与forums表
- #这里专门介绍一个has_many各种Options的用法.
- #:class_name - 仅当model名不能直接由关联名推断出时,就必须指定这个选项值,
- #如:has_many :products 默认情况下,他的model的名字应为product;但是这个关联的model的名为SpecialProduct,这时我们就得指定这个选项值.
- #:conditions - 这个应该比较容易理解,就是取关联表数据时,必须加上:conditions所指定的条件.
- #:order - 就是取关联表数据时,返回一个"order by"的SQL片段.
- #:group - 关联表数据返回一个"group by"的SQL片段,如:"category"
- #:foreign_key - 默认的情况下外键为单数的表名+"_id";当外键与默认的约定不同时,那就得在这里选项里设值了.
- #:dependent - 从字面上看的意思是依赖,相关的意思.比如: has_many :moderatorships, :dependent => :destroy这句代码的意思就是当User
- #执行destroy方法时,那相应也会相应的删除moderatorships表里该user相关联的数据.
- #:exclusively_dependent - 排外依赖.就是关联表的相关记录一条SQL删除,不会因为其他表的关联产生回滚现象.
- #:through: 指定一个Join的方式执行一个跨表查询.
- validates_presence_of :login, :email #分析:这两个字段必填
- validates_length_of :login, :minimum => 2 #分析:login的最小长度为2
- with_options :if => :password_required? do |u| #分析:如果需要密码则:增加如下的验证条件.
- u.validates_presence_of :password_hash
- u.validates_length_of :password, :minimum => 5, :allow_nil => true
- u.validates_confirmation_of :password, :on => :create #分析:一致性检查 仅在user.create的时候
- u.validates_confirmation_of :password, :on => :update, :allow_nil => true
- end
- # names that start with #s really upset me for some reason
- validates_format_of :login, :with => /^[a-z]{2}(?:\w+)?$/i #分析:正则表达式
- validates_format_of :identity_url, :with => /^https?:\/\//i, :allow_nil => true
- # names that start with #s really upset me for some reason
- validates_format_of :display_name, :with => /^[a-z]{2}(?:[.'\-\w ]+)?$/i, :allow_nil => true
- validates_format_of :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, :message => "Please check the e-mail address"[:check_email_message]
- validates_uniqueness_of :login, :email, :case_sensitive => false
- validates_uniqueness_of :display_name, :identity_url, :case_sensitive => false, :allow_nil => true
- before_validation { |u| u.identity_url = nil if u.identity_url.blank? }
- before_validation { |u| u.display_name = u.login if u.display_name.blank? }
- # first user becomes admin automatically
- before_create { |u| u.admin = u.activated = true if User.count == 0 }
- format_attribute :bio
- attr_reader :password
- attr_protected :admin, :posts_count, :login, :created_at, :updated_at, :last_login_at, :topics_count, :activated
- def self.currently_online
- User.find(:all, :conditions => ["last_seen_at > ?", Time.now.utc-5.minutes])
- end
- # we allow false to be passed in so a failed login can check
- # for an inactive account to show a different error
- def self.authenticate(login, password, activated=true)
- find_by_login_and_password_hash_and_activated(login, Digest::SHA1.hexdigest(password + PASSWORD_SALT), activated)
- end
- def self.search(query, options = {})
- with_scope :find => { :conditions => build_search_conditions(query) } do
- find :all, options
- end
- end
- def self.build_search_conditions(query)
- query && ['LOWER(display_name) LIKE :q OR LOWER(login) LIKE :q', {:q => "%#{query}%"}]
- end
- def password=(value)
- return if value.blank?
- write_attribute :password_hash, Digest::SHA1.hexdigest(value + PASSWORD_SALT)
- @password = value
- end
- def reset_login_key!
- self.login_key = Digest::SHA1.hexdigest(Time.now.to_s + password_hash.to_s + rand(123456789).to_s).to_s
- # this is not currently honored
- self.login_key_expires_at = Time.now.utc+1.year
- save!
- login_key
- end
- def moderator_of?(forum)
- moderatorships.count(:all, :conditions => ['forum_id = ?', (forum.is_a?(Forum) ? forum.id : forum)]) == 1
- end
- def to_xml(options = {})
- options[:except] ||= []
- options[:except] << :email << :login_key << :login_key_expires_at << :password_hash << :identity_url
- super
- end
- def password_required?
- identity_url.nil?
- end
- end