has_many :through and foo.bars.include?

hallo everybody,

i already googled the following problem, but there are so many questions regarding "has_many :through", that i just couldn't find what i was looking for. so, i'm really sorry if this has been asked before. if so, just drop me the link.

i have a has_many :through relationship similar to the following example:

class Group < ActiveRecord::Base   has_many :group_memberships,     :dependent => :destroy

  has_many :admins,     :through => :group_memberships,     :source => :user,     :conditions => 'is_admin = true AND pending = false' end

class GroupMembership < ActiveRecord::Base   belongs_to :group   belongs_to :user end

class User < ActiveRecord::Base   has_many :group_memberships

  has_many :administrations,     :through => :group_memberships,     :source => :group,     :conditions => "is_admin = true AND pending = false " end

this is working fine. i even started a new rails-project and tried it there. no problem.

now in an existing project of mine i sometimes get the following: g = Group.first => #<Group id: 1, created_at: "2009-10-28 11:42:36", updated_at: "2009-10-28 11:42:36">

g.admins.include? User.first

ArgumentError: wrong number of arguments (1 for 0)         from /usr/lib64/ruby/gems/1.8/gems/activerecord-2.3.4/lib/ active_record/connection_adapters/mysql_adapter.rb:226:in `kind_of?'         from /usr/lib64/ruby/gems/1.8/gems/activerecord-2.3.4/lib/ active_record/connection_adapters/mysql_adapter.rb:226:in `quote'         from /usr/lib64/ruby/gems/1.8/gems/activerecord-2.3.4/lib/ active_record/base.rb:2392:in `quote_bound_value'         from /usr/lib64/ruby/gems/1.8/gems/activerecord-2.3.4/lib/ active_record/base.rb:2352:in `replace_bind_variables'         from /usr/lib64/ruby/gems/1.8/gems/activerecord-2.3.4/lib/ active_record/base.rb:2352:in `gsub'         from /usr/lib64/ruby/gems/1.8/gems/activerecord-2.3.4/lib/ active_record/base.rb:2352:in `replace_bind_variables'         from /usr/lib64/ruby/gems/1.8/gems/activerecord-2.3.4/lib/ active_record/base.rb:2320:in `sanitize_sql_hash_for_conditions'         from /usr/lib64/ruby/gems/1.8/gems/activerecord-2.3.4/lib/ active_record/base.rb:2231:in `sanitize_sql'         from /usr/lib64/ruby/gems/1.8/gems/activerecord-2.3.4/lib/ active_record/base.rb:2006:in `expand_id_conditions'         from /usr/lib64/ruby/gems/1.8/gems/activerecord-2.3.4/lib/ active_record/base.rb:692:in `exists?'         from /usr/lib64/ruby/gems/1.8/gems/activerecord-2.3.4/lib/ active_record/associations/association_collection.rb:380:in `send'         from /usr/lib64/ruby/gems/1.8/gems/activerecord-2.3.4/lib/ active_record/associations/association_collection.rb:380:in `method_missing_without_paginate'         from /usr/lib64/ruby/gems/1.8/gems/activerecord-2.3.4/lib/ active_record/base.rb:2143:in `with_scope'         from /usr/lib64/ruby/gems/1.8/gems/activerecord-2.3.4/lib/ active_record/associations/association_proxy.rb:206:in `send'         from /usr/lib64/ruby/gems/1.8/gems/activerecord-2.3.4/lib/ active_record/associations/association_proxy.rb:206:in `with_scope'         from /usr/lib64/ruby/gems/1.8/gems/activerecord-2.3.4/lib/ active_record/associations/association_collection.rb:376:in `method_missing_without_paginate'         from /home/n0ne/_files/work/beagile/code/comuungo/vendor/ plugins/will_paginate/lib/will_paginate/finder.rb:170:in `method_missing'         from /usr/lib64/ruby/gems/1.8/gems/activerecord-2.3.4/lib/ active_record/associations/association_collection.rb:336:in `include?'         from (irb):3>>

however, when i reload that association before asking for admins it is working:

g.admins

=>

g.admins.include? User.last

=> false

same thing: Group.first.admins.include? User.last => Exception (see above) Group.first.admin_ids.include? User.last => false

I already checked will_paginate as it is mentioned in the trace. But in my test-project i set up it is working perfectly with the above code and will_paginate installed.

Has anyone ever seen a behaviuor like this? Any clues, hints or tipps?

hallo everybody,

has_many :admins, :through => :group_memberships, :source => :user, :conditions => 'is_admin = true AND pending = false'

Try changing that to :conditions => ['is_admin = true AND pending = false']

Fred

There's clearly some sort of collision going on between an attribute method and the built-in definition of kind_of? - every Ruby object defines the one-argument form, so the fact that it's finding a 0- argument version is a sign.

Somewhat unrelated, but you may want to declare these kind of flag associations using bind variables; it's not strictly necessary, but it's good practice to ensure cross-DB compatibility. In other words, use this:

:conditions => ["is_admin = ? AND pending = ?", true, false]

Otherwise, you may get weird errors when you switch your DB (to, for example, an in-memory SQLite3 for test speed) and the new DB doesn't escape booleans the same way.

--Matt Jones

thanks a lot for your replies!

i already changed my :conditions. but i have an additional question about that: should i change :order-statements accordingly (to also include the brackets)?

as for my original problem: thanks matt! your post put me into a new direction. i really found an old (obsolete) 'type_of'-attribute inside my user-model. your explanation seems to have a point. i did not try it yet, but i'm pretty sure that it would solve my problem.

thanks again.

thanks a lot for your replies!

i already changed my :conditions. but i have an additional question about that: should i change :order-statements accordingly (to also include the brackets)?

No. (and changing conditions isn't necessary - I just had a (probably wrong) hunch about what might be wrong)). A dangerously named attribute/method is far more likely

Fred

just tried it. removing the kind_of-attribute did the trick! THANKS! that bug was really getting annoying.