Hi Railers,
I''ve got a Categories table.
I want it to act as a list within the scope of the parent_id AND the
site_id.
Categories table :
id
label
site_id
parent_id
So, in my Category class, I have :
acts_as_list :scope => ''site_id = #{site_id} AND parent_id = #
{parent_id}''
The problem is that when I try to move_up a Category with a parent_id
that is null, the generated query (found in my development.log) is
"SELECT * FROM categories WHERE (site_id = 1 AND parent_id = AND
position = 3)" which gives me an error (because of "parent_id =
AND").
So, my question is "how can I solve this problem?".
Many thanks in advance for you help that will be much appreciated!
Thomas Balthazar.
P.S. : if I only set the scope to parent_id, I have no problem, the
generated query is "SELECT * FROM categories WHERE (parent_id IS
NULL)"
Thomas,
This happens because the code for acts_as_list behaves differently
when the scope is a symbol versus a string like the one you''re using.
When the scope is a symbol, acts_as_list knows how to check for null
and generate "IS NULL" as the condition. When you pass a string as
the scope, that string is used verbatim as the condition, with
runtime substitution of the values of any interpolated variables (the
stuff inside the #{...}).
Perhaps it would help to look at the source code at http://
ar.rubyonrails.com/classes/ActiveRecord/Acts/List/
ClassMethods.html#M000022. Be sure to click on the "Show Source" link
at the bottom of the acts_as_list entry, if it isn''t already showing.
Line 35 sets up some default key / value pairs. These will be
augmented (and possibly overridden) at line 36 by any that you pass
in, like :scope.
If you pass in ":scope => :some_symbol", lines 41 - 49 define a
method called scope_condition() that looks like this:
def scope_condition
if parent_id.nil?
"parent_id IS NULL"
else
"parent_id = #{parent_id}"
end
end
and behaves as you expect when the runtime value of the symbol is nil.
If your :scope value is anything but a symbol (a string, in your
case), line 51 is executed instead. It generates a method that looks
like:
def scope_condition()
"site_id = #{site_id} AND parent_id = #{parent_id}"
end
Unfortunately, all that happens here when parent_id is nil is what
you saw in your log; i.e., it is interpolated as no character. You
might expect it to create something like:
site_id = 123 AND parent_id = nil
at runtime, but even that wouldn''t be helpful. You can see a
difference in how nil is handled by opening an irb session and
entering "puts nil", followed by "puts #{nil}".
If it''s any consolation, the example used in the acts_as_list
documentation ("acts_as_list :scope => ‘todo_list_id = #
{todo_list_id} AND completed = 0’") will fail in the same way that
yours does if todo_list_id is nil.
Hope this helps,
David
On Nov 25, 2005, at 8:06 AM, Thomas Balthazar wrote:
> Hi Railers,
>
> I''ve got a Categories table.
> I want it to act as a list within the scope of the parent_id AND
> the site_id.
>
> Categories table :
> id
> label
> site_id
> parent_id
>
> So, in my Category class, I have :
> acts_as_list :scope => ''site_id = #{site_id} AND parent_id = #
> {parent_id}''
>
> The problem is that when I try to move_up a Category with a
> parent_id that is null, the generated query (found in my
> development.log) is
> "SELECT * FROM categories WHERE (site_id = 1 AND parent_id = AND
> position = 3)" which gives me an error (because of "parent_id =
AND").
>
> So, my question is "how can I solve this problem?".
>
> Many thanks in advance for you help that will be much appreciated!
>
> Thomas Balthazar.
>
> P.S. : if I only set the scope to parent_id, I have no problem, the
> generated query is "SELECT * FROM categories WHERE (parent_id IS
> NULL)"
> _______________________________________________
> Rails mailing list
> Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
> http://lists.rubyonrails.org/mailman/listinfo/rails
Hello David, Thank you for your help! I noticed the same thing, and I submitted a bug report regarding this. You can read it here : <http://dev.rubyonrails.org/ticket/3018>. It was posted 6 days ago, but is still not being managed. Kind regards, Thomas. On 11/28/05, David Rupp <rails-T+GAArMh60A/u7dgPfZd+NBPR1lH4CV8@public.gmane.org> wrote:> Thomas, > > This happens because the code for acts_as_list behaves differently > when the scope is a symbol versus a string like the one you''re using. > When the scope is a symbol, acts_as_list knows how to check for null > and generate "IS NULL" as the condition. When you pass a string as > the scope, that string is used verbatim as the condition, with > runtime substitution of the values of any interpolated variables (the > stuff inside the #{...}). > > Perhaps it would help to look at the source code at http:// > ar.rubyonrails.com/classes/ActiveRecord/Acts/List/ > ClassMethods.html#M000022. Be sure to click on the "Show Source" link > at the bottom of the acts_as_list entry, if it isn''t already showing. > > Line 35 sets up some default key / value pairs. These will be > augmented (and possibly overridden) at line 36 by any that you pass > in, like :scope. > > If you pass in ":scope => :some_symbol", lines 41 - 49 define a > method called scope_condition() that looks like this: > > def scope_condition > if parent_id.nil? > "parent_id IS NULL" > else > "parent_id = #{parent_id}" > end > end > > and behaves as you expect when the runtime value of the symbol is nil. > > If your :scope value is anything but a symbol (a string, in your > case), line 51 is executed instead. It generates a method that looks > like: > > def scope_condition() > "site_id = #{site_id} AND parent_id = #{parent_id}" > end > > Unfortunately, all that happens here when parent_id is nil is what > you saw in your log; i.e., it is interpolated as no character. You > might expect it to create something like: > > site_id = 123 AND parent_id = nil > > at runtime, but even that wouldn''t be helpful. You can see a > difference in how nil is handled by opening an irb session and > entering "puts nil", followed by "puts #{nil}". > > If it''s any consolation, the example used in the acts_as_list > documentation ("acts_as_list :scope => ''todo_list_id = # > {todo_list_id} AND completed = 0''") will fail in the same way that > yours does if todo_list_id is nil. > > Hope this helps, > David > > On Nov 25, 2005, at 8:06 AM, Thomas Balthazar wrote: > > > Hi Railers, > > > > I''ve got a Categories table. > > I want it to act as a list within the scope of the parent_id AND > > the site_id. > > > > Categories table : > > id > > label > > site_id > > parent_id > > > > So, in my Category class, I have : > > acts_as_list :scope => ''site_id = #{site_id} AND parent_id = # > > {parent_id}'' > > > > The problem is that when I try to move_up a Category with a > > parent_id that is null, the generated query (found in my > > development.log) is > > "SELECT * FROM categories WHERE (site_id = 1 AND parent_id = AND > > position = 3)" which gives me an error (because of "parent_id = AND"). > > > > So, my question is "how can I solve this problem?". > > > > Many thanks in advance for you help that will be much appreciated! > > > > Thomas Balthazar. > > > > P.S. : if I only set the scope to parent_id, I have no problem, the > > generated query is "SELECT * FROM categories WHERE (parent_id IS > > NULL)" > > _______________________________________________ > > Rails mailing list > > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > > http://lists.rubyonrails.org/mailman/listinfo/rails > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >