0

我在 Rails 中编写了一个黑客新闻克隆来学习框架,并遇到了在模型中调用辅助方法的问题:

class User < ActiveRecord::Base
  has_secure_password validations: false

  has_many :posts

  validates :name,
    presence: { message: username_error_message },
    uniqueness: { case_sensitive: false, message: username_error_message },
    length: { minimum: 2, maximum: 15, message: username_error_message }

  validates :password, 
    presence: { message: password_error_message },
    length: { minimum: 4, message: password_error_message }

private
  def username_error_message
    "Usernames can only contain letters, digits, dashes and underscores, and should be     between 2 and 15 characters long. Please choose another."
  end

  def password_error_message
    "Passwords should be a least 4 characters long. Please choose another."
  end
end

我收到以下错误(Rails 4):

undefined local variable or method `username_error_message' for #<Class:XXX>
4

4 回答 4

1

您可以对重复的错误消息使用常量,它会起作用。

class User < ActiveRecord::Base
  has_secure_password validations: false

  has_many :posts

  USERNAME_ERROR_MESSAGE = "Usernames can only contain letters, digits, dashes and underscores, and should be between 2 and 15 characters long. Please choose another."
  PASSWORD_ERROR_MESSAGE = "Passwords should be a least 4 characters long. Please choose another."

  validates :name,
    presence: { message: USERNAME_ERROR_MESSAGE },
    uniqueness: { case_sensitive: false, message: USERNAME_ERROR_MESSAGE },
    length: { minimum: 2, maximum: 15, message: USERNAME_ERROR_MESSAGE }

  validates :password, 
    presence: { message: PASSWORD_ERROR_MESSAGE },
    length: { minimum: 4, message: PASSWORD_ERROR_MESSAGE }

end

此外,还有一个小问题:如果每个字段都有多个验证条件失败,则会重复错误消息。一种解决方案是编写自定义验证方法,如下所示:http: //guides.rubyonrails.org/active_record_validations.html#custom-methods

于 2013-10-09T04:44:56.217 回答
0

尝试使用类方法:

validates :name,
    presence: { message: Proc.new { username_error_message } },
    uniqueness: { case_sensitive: false, message: Proc.new { username_error_message } },
    length: { minimum: 2, maximum: 15, message: Proc.new { username_error_message } }

  validates :password, 
    presence: { message: Proc.new { password_error_message } },
    length: { minimum: 4, message: Proc.new { password_error_message } }

private
  def self.username_error_message
    "Usernames can only contain letters, digits, dashes and underscores, and should be     between 2 and 15 characters long. Please choose another."
  end

  def self.password_error_message
    "Passwords should be a least 4 characters long. Please choose another."
  end
于 2013-10-09T03:46:49.407 回答
0

根本问题是您在定义方法之前访问它们。这个问题本身与它们是私有、常量、实例方法还是类方法无关。

User在定义您的类时引用这些方法。引用存在于{}作为参数传递给方法调用的哈希构造函数中validates,这意味着它validates调用时得到评估。这不像您将一个块传递给validates稍后评估的块。

如果您在引用之前将定义移至它们,它将解决这个基本问题,但您将它们定义为实例方法并将它们引用为类方法也是正确的。您需要使您的定义模式与您的访问模式一致(例如,通过将方法定义为类方法)。

(注意:除了其他答案中提到的那些之外,还有无数其他选项可用于定义和引用这些字符串,包括类变量、类局部变量等。它们主要在访问位置和访问方式方面有所不同。您甚至可以使用实例变量和方法,尽管在这种情况下这会很奇怪,需要您实例化一个对象才能引用它们。关键是 Ruby 具有丰富的可能性,当您有这些可能性时,非常值得研究/理解它们时间。)

于 2013-10-09T14:42:33.713 回答
-1

尝试这个

class User < ActiveRecord::Base
  has_secure_password validations: false

  has_many :posts

  validates :name,
    presence: { message: self.username_error_message },
    uniqueness: { case_sensitive: false, message: self.username_error_message },
    length: { minimum: 2, maximum: 15, message: self.username_error_message }

  validates :password, 
    presence: { message: self.password_error_message },
    length: { minimum: 4, message: self.password_error_message }


  def username_error_message
    "Usernames can only contain letters, digits, dashes and underscores, and should be           between 2 and 15 characters long. Please choose another."
  end

  def password_error_message
    "Passwords should be a least 4 characters long. Please choose another."
   end
end
private :username_error_message, :password_error_message

我只是添加了一些“自我”。在方法调用之前给它这个实例的上下文。我也更改了私有声明方法

于 2013-10-09T04:02:47.067 回答