Rails ActiveRecord:在哪里定义方法?

时间:2017-02-14 13:51:16

标签: ruby-on-rails ruby activerecord

我对Rails的ActiveRecord有疑问。

例如,我有Service模型,Servicename列。

这是app/model/service.rb

class Service < ActiveRecord::Base

  def self.class_method
    puts 'This is class method'
  end

  def instance_method
    puts 'This is instance method'
  end
end

然后我可以做,

Service.class_method #=> 'This is class method'

Service.find(1).instance_method #=> 'This is instance method'

这很容易。但是当我在Array中获得ActiveRecord Instance时,例如

Service.where(id: [1,2,3])

我需要像

这样的方法
Service.where(id: [1,2,3]).sample_method

def sample_method
  self.length
end

但是如何以及在何处定义Active Record Array的方法?我想像其他Service类或实例一样处理此对象。

感谢。

2 个答案:

答案 0 :(得分:0)

get_countget_name这样的方法有点无意义......为什么不这样做:

Service.count

Service.find(1).name

count等类方法和name等实例方法(即数据库列名)都是 public - 因此您无需定义自己的getter方法

至于你的第二个例子,你可以只写下面的内容:

Service.where(id: [1,2,3]).map{ |s| s.name }

或等效地:

Service.where(id: [1,2,3]).map(&:name)

但是以下实际上更有效,因为它在SQL 中而不是在ruby中执行计算。 (如果你对我的意思感到困惑,请尝试运行两个版本并比较日志中生成的SQL):

Service.where(id: [1,2,3]).pluck(:name)

答案 1 :(得分:0)

首先,where返回一个ActiveRecord :: Relation对象,而不是一个数组。它的行为类似于数组,但是继承了一个加载更多方法来处理数据/构造SQL以查询数据库。

如果要向ActiveRecord :: Relation类添加其他功能,可以执行以下操作:

class ActiveRecord::Relation 
  def your_method
    # do something
  end
end

这需要驻留在有意义的地方,例如lib目录或config / initializers。

这应该允许你做类似

的事情
Service.where(id: [1,2,3]).your_method

你可以为任何Ruby类做类似的事情,比如Hash或Array类。

然而,除了扩展/覆盖Rails / Ruby源类之外,几乎总是一个更好的解决方案...