views:

63

answers:

2

I want to write a named scope to get a record from its id.

For example, I have a model called Event, and I want to simulate Event.find(id) with use of named_scope for future flexibility.

I used this code in my model:

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

and I call it from my controller like Event.from_id(id). But my problem is that it returns an array of Event objects instead of just one object.

Thus if I want to get event name, I have to write

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

while what I want is

event = Event.from_id(id)
event.name

Am I doing something wrong here?

+3  A: 

There's no need to use a scope here. You could just do Event.find_by_id id.
The difference between find and find_by_id is that the first one will raise an ActiveRecordNotFoundException if the record does not exist. The second one will just return nil.

Writing a scope to get the record by it's id is a very bad id as it is something which is already provided natively by rails.

Damien MATHIEU
Hi Damien,thanks for the quick reply. Why i want to have this as a named scope is because later I might want to get only the active eventsSo then I can change only the named scope with out breaking the existing code (like only adding active=1)Please let me know your commentscheers,sameera
sameera207
@sameera you could just add a generic method (`def ... end`); it doesn't have to be a named scope.
Pavel Shved
+5  A: 

As Damien mentions, using a custom scope just to look up by ID isn't advisable. But to answer your question:

Finding records with named_scope will always return an ActiveRecord::NamedScope::Scope object, which behaves like an array. If there is just a single record returned by your query, you can use the first method to get the ActiveRecord object directly, like this:

event = Event.from_id(id).first
event.name # will work as you expect
Jimmy Cuadra
hi JimmyThanks for the quick answer. Why I want to have a named scope is (as I mentioned in Damien's comment)because later I might want to get only the active events So then I can change only the named scope with out breaking the existing code (like only adding active=1) Please let me know your comments cheers, sameera
sameera207