我想写一个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
我在这里做错了吗?
答案 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
find
和find_by_id
之间的区别在于,如果记录不存在,第一个将引发ActiveRecordNotFoundException
。第二个将返回零。
编写一个范围以通过它的id获取记录是一个非常糟糕的ID,因为它已经由rails本地提供。