named_scope and .first?
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', :resourc开发者_运维问答e_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.
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.
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).
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.
精彩评论