ruby-on-rails - 在 Rails 4 的模型/类中定义自定义方法

标签 ruby-on-rails ruby ruby-on-rails-4 class-method

我有以下模型:

class ActivityLog < ActiveRecord::Base
  validates :user_id, :instance_id, :action, presence: true
  validates :user_id, :instance_id, :action, numericality: true

  def log
    ActivityLog.create(
      user_id: current_user ? current_user.id : -1,
      instance_id: instance_id,
      action: actions.index(action)
      )
  end

  private 

  def actions
    ['start','stop','create','destroy']
  end

end

当我从 Rails 控制台调用以下行时,出现错误:

ActivityLog.log(user_id: 1, instance_id:1, action: 'create')

# Error returned from console
NoMethodError: undefined method `log' for #<Class:0x007fb4755a26a8>

为什么我的方法调用不起作用?我在类里面定义了它,但它说它是未定义的。我错过了什么或误解了什么?谢谢。

最佳答案

创建方法log

假设您有一个类User,并且在该类中,您定义了方法has_cell_phone。 (该方法的内容无关紧要。)当您在类中将方法定义为 def has_cell_phone 时,可以在任何 User 对象上调用该方法。虽然 class User 本身是一个 class 对象,但您可以在直接类为 User 的对象上调用它。用正确的术语来说,您将为 User 类的实例编写一个实例方法

您收到该错误是因为您定义的方法 log 仅适用于 ActivityLog 类的_instance。如果执行以下操作,则可以根据当前代码正确调用 log:

activity_log = ActivityLog.create  # with required params
activity_log.log

其次,您正在调用带有参数的log,而您的方法定义不需要任何参数。 (这看起来像 def log(params)。)

现在,您可以在此处修改现有代码。当您想调用整个 类(即类本身)的方法时,您可以在类方法定义前加上关键字self。例如,对于 User 类,它将是 def self.create_user_with_cell_phone。您还可以向该方法添加参数。您在“方法调用”行中提供的参数,我会将它们添加到您的类方法中,如下所示:

def self.log(instance_id, action)
  # ...
end

ActivityLog.log(1, 'create')

您不需要包含 user_id,因为根据您的逻辑,它会检查 current_user 对象是否为 true,并且从那里开始。

创建类常量

再看你的问题,我发现你定义了一个方法actions。还记得我说过的实例方法吗?由于 actions 似乎将始终保持不变,因此我建议您将其设为一个!为此,建议您在类中的任何方法定义之前放置以下行。

ACTIONS = ['start','stop','create','destroy']

然后,任何时候你想在 ActivityLog 类中调用 ACTIONS 时,你都可以执行以下操作:ACTIONS.index(action) .如果您想在其类的外部 调用此常量,您可以这样做:ActivityLog::ACTION。它与类方法调用的语法相似,而是使用:: 将类与常量分开。重新检查您的代码,它现在应该如下所示:

class ActivityLog < ActiveRecord::Base
  ACTIONS = ['start','stop','create','destroy']

  validates :user_id, :instance_id, :action, presence: true
  validates :user_id, :instance_id, :action, numericality: true

  def self.log(instance_id, action)
    ActivityLog.create(
      user_id: (current_user ? current_user.id : -1),
      instance_id: instance_id,
      action: ACTIONS.index(action)
    )
  end
end

关于ruby-on-rails - 在 Rails 4 的模型/类中定义自定义方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31462005/

相关文章:

ruby-on-rails-4 - 如何根据服务器自动设置RAILS_ENV

css - Rails 应用程序中 CSS "background:url"属性的正确语法是什么?

mysql - Rails ActiveRecord 表索引 - 什么时候应该使用它们?

ruby - hbase 外壳 : TypeError: can't dup NilClass

ruby - 使用 SSH 克隆存储库时出现 "permission denied"错误?

javascript - Rails 4.1 has_many.js 错误

ruby-on-rails - 没有要加载的文件——rubygems (LoadError)

ruby-on-rails - Rails 3 - 自己的验证消息而不是 "is not a number"

ruby-on-rails - Rails 通过 div 包装有错误的字段

ruby-on-rails - Rails文件上载(回形针)编辑