4

I can return a collection of objects, with only one (:limit => 1) but is there a way to return the .first() object only, like not within a collection?

named_scope :profile, :conditions => {:association => 'owner', :resource_type => 'Profile'}, :limit => 1    # => collection of 1 profile but I want the profile only NOT in a collection or array

the workaround is simply to apply .first() to the results, but I'd just like to clean up the code and make it less error prone.

Andrew Lank
  • 1,607
  • 1
  • 15
  • 29
  • I would have to say the vote is unanimous, A method it is, and works quite well, first time I see the where(), quite handy. Thanks all. – Andrew Lank Jun 09 '11 at 21:22

3 Answers3

7

You'll probably need to create a class method instead:

def self.profile
  where(:association => 'owner', :resource_type => 'Profile').first
end

Note that with Rails 3 you should be using the where(...) syntax, and that when doing .first, you don't need to specify the limit.

Dylan Markow
  • 123,080
  • 26
  • 284
  • 201
5

First off, if you're using Rails 3 you should be using scope instead of named_scope. Same thing, different, err, name (named_scope will still work, but it is deprecated). Now that that is out of the way…

A scope (or named scope) takes two arguments (a symbol and either a lambda or a hash) and defines a class method on that model that returns an ActiveRecord::Relation, which is why you're able to chain methods on it.

first, like find or all, returns an actual result from the database. For this reason it won't work in a scope.

All that said, you can define your own class method on your model that gives the behavior you're wanting (as 2 people already answered while I was typing this). This is actually recommended over using scopes by many well-respected devs in the Rails community. Since using the scope class macro just defines class methods itself anyways, there isn't really a downside to this, and it has the benefit of flexibility (like in your case here).

coreyward
  • 77,547
  • 20
  • 137
  • 166
  • LOL, I'm such a lame, I saw the deprecation warnings but never realized (or read them!) they were related to my newly added named_scopes, thanks for making me see the light, changing to scope. – Andrew Lank Jun 09 '11 at 21:26
3

Define a class method to do this:

def profile
  where(:association => "owner", :resource_type => 'Profile').first
end

The first already does an implicit limit 1 on the query, AND will order it by the primary key of the table so you'll always get the first.

Ryan Bigg
  • 106,965
  • 23
  • 235
  • 261