如何在Rails中使named_scope返回一个值而不是一个数组?

时间:2010-05-29 07:00:53

标签: ruby-on-rails ruby activerecord find

我想写一个named scope来获取其ID的记录。

例如,我有一个名为Event的模型,我希望使用Event.find(id)来模拟named_scope,以便将来灵活使用。

我在我的模型中使用了这段代码:

named_scope :from_id, lambda { |id| {:conditions => ['id= ?', id] } }

我从我的控制器中调用它,如Event.from_id(id)。但我的问题是它返回一个Event个对象的数组而不是一个对象。

因此,如果我想获得事件名称,我必须写

event = Event.from_id(id)
event[0].name

而我想要的是

event = Event.from_id(id)
event.name

我在这里做错了吗?

3 个答案:

答案 0 :(得分:12)

在这种情况下,我会创建一个类方法

def self.from_id(id)
  self.find(id).first
end

另一个例子:

class Invoice
  def self.number
    self.find(:first, 
      :select => "max(number) As last, max(number)+1 As next", 
      :conditions => "type = 'SalesOrder'")
  end
end

这样的方法比named_scope更好。您可以拨打Invoice.number.next,优于named_scope返回Invoice.number[0].next

答案 1 :(得分:10)

正如Damien所提到的,使用自定义范围只是为了通过ID查找是不可取的。但要回答你的问题:

使用named_scope查找记录将始终返回ActiveRecord::NamedScope::Scope对象,其行为类似于数组。如果查询只返回一条记录,则可以使用first方法直接获取ActiveRecord对象,如下所示:

event = Event.from_id(id).first
event.name # will work as you expect

答案 2 :(得分:5)

此处无需使用示波器。你可以做Event.find_by_id id findfind_by_id之间的区别在于,如果记录不存在,第一个将引发ActiveRecordNotFoundException。第二个将返回零。

编写一个范围以通过它的id获取记录是一个非常糟糕的ID,因为它已经由rails本地提供。