新手:关于如何清理,改进,安排,缩短模型的提示?

时间:2012-03-02 23:44:39

标签: ruby-on-rails ruby-on-rails-3 model code-formatting

我发现我的模型变得越来越混乱和混乱。下面是我的实际用户模型,有关清理和安排事项以获得更好的可读性的任何建议吗?

我对这一切的不可读性感到沮丧,因此欢迎任何有关此代码的一般想法。我真的很喜欢将它们放在一起做同样的代码,但就像我现在只是一个大块无法读取的混乱。

# == Schema Information
#
# Table name: users
#
#  id                     :integer(4)      not null, primary key
#  email                  :string(255)     default(""), not null
#  encrypted_password     :string(255)     default(""), not null
#  reset_password_token   :string(255)
#  reset_password_sent_at :datetime
#  remember_created_at    :datetime
#  sign_in_count          :integer(4)      default(0)
#  current_sign_in_at     :datetime
#  last_sign_in_at        :datetime
#  current_sign_in_ip     :string(255)
#  last_sign_in_ip        :string(255)
#  password_salt          :string(255)
#  confirmation_token     :string(255)
#  confirmed_at           :datetime
#  confirmation_sent_at   :datetime
#  unconfirmed_email      :string(255)
#  failed_attempts        :integer(4)      default(0)
#  unlock_token           :string(255)
#  locked_at              :datetime
#  authentication_token   :string(255)
#  username               :string(255)
#  is_blocked             :boolean(1)
#  is_deleted             :boolean(1)
#  role                   :string(255)
#  slug                   :string(255)
#  created_at             :datetime        not null
#  updated_at             :datetime        not null
#  last_seen              :datetime
#  credits                :integer(4)
#

class User < ActiveRecord::Base


  devise :database_authenticatable,
         :registerable,
         :recoverable,
         :rememberable,
         :trackable,
         :validatable,
         :token_authenticatable,
         :encryptable,
         :confirmable,
         :lockable,
         :timeoutable,
         :lastseenable
  #:omniauthable

  attr_accessible :username,
                  :login,
                  :email,
                  :password,
                  :password_confirmation,
                  :remember_me,
                  :profile_attributes,
                  :is_moderated,
                  :is_blocked,
                  :is_deleted,
                  :credits,
                  :role,
                  :confirmed_at,
                  :last_seen,
                  :invite_code


  attr_accessor :login
  #attr_accessor :invite_code

  has_one :profile
  has_one :account

  accepts_nested_attributes_for :profile
  accepts_nested_attributes_for :account

  extend FriendlyId
  friendly_id :username, use: :slugged

  before_create :default_values


  # AFTER CREATE -------------------------------------------------------------------------------------------------------

  after_create :add_account

  def add_account
    self.create_account

  end

  def default_values
    self.credits = -1
    self.invite_code = invite_code
    #self.reset_authentication_token!
    beta = Beta.where(:code => invite_code).first
    beta.used = 1
    beta.save
  end


  # ROLES --------------------------------------------------------------------------------------------------------------

  before_create :setup_default_role_for_new_users
  ROLES = %w[admin default vip]


  # VALIDATIONS --------------------------------------------------------------------------------------------------------


  before_validation { |u| u.username.downcase! }
  before_validation { |u| u.email.downcase! }

  validates_uniqueness_of :username,
                          :email,
                          :case_sensitive => false

  validates_presence_of :email,
                        :username,
                        :invite_code

  validates :username,
            :exclusion => {:in => ["admin", "root", "administrator", "superuser", "myhost", "support", "contact", "chat", "boo"],
                           :message => "is reserved"}


  validate :check_email, :on => :create
  validate :check_invite_code, :on => :create

  def check_invite_code
    errors.add(:invite_code, "Invalid code") unless Beta.where(:code => invite_code, :used => 0).first
  end

# Devise
  def active_for_authentication?
    super && !is_deleted
  end


# Devise
  def confirm!
    #welcome_message
    #super
  end

# Devise
  def soft_delete
    update_attribute(:deleted_at, Time.current)
  end


  def is_moderated?
    return self.is_moderated
  end

  def is_online?
    if self.last_seen < 10.minutes.ago
      return true
    else
      return false
    end
  end

  private

  def setup_default_role_for_new_users
    if self.role.blank?
      self.role = "default"
    end
  end


  def welcome_message
    #::Devise.mailer.welcome_instructions(self).deliver
    ::Devise.mailer.welcome_instructions(self).deliver
  end


  def check_email

    host = email.split("@").last
    username = email.split("@").first

    reserved_word_filters = %w(admin hostmaster root support )

    if /.*(#{reserved_word_filters.join("|")}).*\@/.match(email)
      errors.add(:email, "Invalid username in email")
    end

    if email.include? 'myhost'
      errors.add(:email, "Invalid email")
    end

  end


# DEVISE:  --------------------------------------------------------------------------------------------------

  protected


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


end

3 个答案:

答案 0 :(得分:3)

我要做的唯一清理模型的方法是模块化它们。 DHH自己发布了一个很棒的example gist,展示了如何清理一个过大的模型。我不认为你的特别大,但如果你想把所有设计的东西都移到自己的模块中,它肯定会让你的模型更加整洁。

答案 1 :(得分:2)

1。 您的代码中包含return个语句。除非您在方法中过早地返回某些内容,否则返回方法中的最后一个语句就是Ruby自动返回的内容。像这样:

def square(x)
  val = x**2
  return val
end

可缩短为:

def square(x)
  x**2
end

这是一个人为的例子,但确实如此。

2。 许多self都是多余的。在模型实例的范围中,当将属性设置为值或调用方法时,您不需要前置self,因为该方法/变量已从同一范围调用。

答案 2 :(得分:2)

你也可以养成将布尔值作为头等表达式的习惯。例如,

def is_online?
  if self.last_seen < 10.minutes.ago
    return true
  else
    return false
  end
end

更清楚地写成:

def is_online?
  last_seen < 10.minutes.ago
end