Is AR find(:all) a 100% named_scope?

hi there,
I have a method in a model that concatenates named_scopes at later
points in
the method if certain conditions given. The concatenations go ok when
all
that concatenation is done with named_scopes, but it blows when
ActiveRecord.all is used in it

see it in the gist: is_find_all_a_named_scope?.rb · GitHub

I could of course write that in some other way, but the question would
be:
could AR.all be turned into a NamedScope and not an Array?

any ideas? in the mean time I will refactor my code and make my specs
happy
:slight_smile:

cheers,
joaquin

gs = if privates
            self.privates # with named_scopes everything runs fine
          else
            self.all # here we won't get a NamedScope, instead it'll
be an Array
          end

Try:

   gs = if privates
          self.privates
        else
          self
        end

在 2009/11/9 下午 7:35 時, Joaquin Rivera P. 寫到:

any ideas? in the mean time I will refactor my code and make my
specs happy :slight_smile:

cheers,
joaquin

HeChian H.
[email protected]

On 09 Nov 2009, at 12:35, Joaquin Rivera P. wrote:

any ideas? in the mean time I will refactor my code and make my
specs happy :slight_smile:

Well, the implementation of AR.all is not a named_scope as you
obviously found out:

   # This is an alias for find(:all).  You can pass in all the

same arguments to this method as you can
# to find(:all)
def all(*args)
find(:all, *args)
end

A quick google search revealed this blog post:
http://www.neeraj.name/blog/articles/871-fixing-activerecord-base-all-and-making-it-friendlier-to-named_scope

It outlines both the problem and provides a solution. I do agree that
since AR is clearly pushing chained scopes as a way to build queries,
a named scope implementation would be better. But named scopes have
quite a bit of work ahead, since arguments don’t get overridden if a
subsequent scope defines them differently etc. Example: if you
make :active => true the default scope and then make a named_scope
of :inactive, defined as :active => false, you’ll get a contradictory
query.

On the other hand, Rails is open source and well thought out and
tested contributions do make it into the core, so it’s only a matter
of someone stepping up to get it sorted. Other ORM options have
already tackled these problems more elegantly afaik, like Datamapper
and Arel.

Best regards

Peter De Berdt

hi all,
thanks for you reply,

2009/11/9 Peter De Berdt [email protected]

I could of course write that in some other way, but the question would be:
arguments to this method as you can
# to find(:all)
def all(*args)
find(:all, *args)
end

A quick google search revealed this blog post:
http://www.neeraj.name/blog/articles/871-fixing-activerecord-base-all-and-making-it-friendlier-to-named_scope

Peter yep, nice post, only for the moment I don’t feel like patching
AR::Base, and I get lots of warnings when running my specs:

/home/joahking/dev/rails/tucamon/app/models/group.rb:44: warning:
multiple
values for a block parameter (0 for 1)
from
/home/joahking/dev/rails/tucamon/vendor/rails/activerecord/lib/active_record/named_scope.rb:92

line 44: named_scope :all, lambda { |args| args ||= {} }

I’ll go with HeChian H. idea, it ended like this:
gs = if PrivacyLevels.include? privacy
self.send privacy
else
self # AR itself
end

if name
  gs.named_like name
else
  gs.all # and all again
end

I know it’s not a very general solution, but it keeps all them specs
green
:slight_smile:

I have to move on given my deadlines, but if I stumble again I’ll give a
second thought

thanks for your responses,
joaquin

It outlines both the problem and provides a solution. I do agree that
since

problems more elegantly afaik, like Datamapper and Arel.

Best regards

Peter De Berdt

On Nov 9, 11:35 am, Joaquin Rivera P. [email protected] wrote:

ActiveRecord.all is used in it

see it in the gist:is_find_all_a_named_scope?.rb · GitHub

I could of course write that in some other way, but the question would be:
could AR.all be turned into a NamedScope and not an Array?

It could be interesting to do this. For now instead of doing self.all
you could try self.all.scoped({})

Fred