A possible bug in Has_many :through using :soucre


#1

I’ve been stumped on this for a few days and I’m not sure if it’s an
error
on my end or an actual bug.
I have a system where I have workshops and users. Workshops have
students,
presenters, and troubleshooters. I wanted to represent this simply by
using has_many :through with :source.

Workshop

has_many :presenters, :through =>:presenterships, :source=>:user

This actually works great. However, I am running into a really
interesting
problem when doing the assignments:

This works:

@u = User.find 1
@w = Workshop.find 1
@w.presenterships.create :user_id => u.id

But this fails:

@u = User.find 1
@w = Workshop.find 1
@w.presenterships.create :user => u

Notice t he assignment of the object instead of the id field.

The trickiest part of all this is that I get a really strange error
message:

ActiveRecord::AssociationTypeMismatch: User expected, got User
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.2
/lib/active_recor
d/associations/association_proxy.rb:148:in raise_on_type_mismatch' from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.2 /lib/active_recor d/associations/belongs_to_association.rb:22:inreplace’
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.2
/lib/active_recor
d/associations.rb:900:in user=' from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.2 /lib/active_recor d/base.rb:1673:inattributes=’
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.2
/lib/active_recor
d/base.rb:1672:in attributes=' from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.2 /lib/active_recor d/base.rb:1506:ininitialize_without_callbacks’
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.2
/lib/active_recor
d/callbacks.rb:225:in initialize' from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.2 /lib/active_recor d/associations/has_many_association.rb:13:inbuild’
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.2
/lib/active_recor
d/associations/association_collection.rb:93:in `create’
from (irb):5

I’ve pasted my classes below. The migrations are standard
(presenterships
just has its own id and the two foreign keys). I’d appreciate any
insight.
I have a workaround but I was just wondering if this was a bug or a
limitation.

class Workshop < ActiveRecord::Base

has_many :presenterships
has_many :presenters, :through =>:presenterships, :source=>:user

end

class Presentership < ActiveRecord::Base
belongs_to :workshop
belongs_to :user
end

class User

lots of validations

end


#2

i tested your example exactly as you posted it and all works fine for
me using Rails 1.1.6.

w = Workshop.find 1
=> #<Workshop:0xb797928c @attributes={“name”=>“RailsConf”, “id”=>“1”}>

users = User.find(:all)
=> [#<User:0xb792f650 @attributes={“name”=>“Bob”, “id”=>“1”}>,
#<User:0xb792f614 @attributes={“name”=>“Joe”, “id”=>“2”}>]

w.presenterships.create :user_id => users[0].id
=> #<Presentership:0xb7923828
@errors=#<ActiveRecord::Errors:0xb7922d60 @errors={},
@base=#<Presentership:0xb7923828 …>>, @attributes={“workshop_id”=>1,
“id”=>1, “user_id”=>1}, @new_record=false>

w.presenterships.create :user => users[1]
=> #<Presentership:0xb791cd5c
@errors=#<ActiveRecord::Errors:0xb791c438 @errors={},
@base=#<Presentership:0xb791cd5c …>>, @attributes={“workshop_id”=>1,
“id”=>2, “user_id”=>2}, @user=#<User:0xb792f614
@attributes={“name”=>“Joe”, “id”=>“2”}>, @new_record=false>

w.presenters true
=> [#<User:0xb7913be4 @attributes={“name”=>“Bob”, “id”=>“1”}>,
#<User:0xb79139c8 @attributes={“name”=>“Joe”, “id”=>“2”}>]


#3

Yeah… forgot to mention that I am using 1.2.1 (and now 1.2.2)
Could you confirm this?


#4

@Chris:
Thanks for trying to duplicate. I’ve recreated this in a new project and
it
worked fine, so that means the current project is doing something
something
else that’s causing the incompatibility issue.

I was afraid it was something I did, and looks like I was right.


#5

works for 1.2.2 for me as well

RAILS_GEM_VERSION
=> “1.2.2”

w = Workshop.find :first
=> #<Workshop:0xb7629168 @attributes={“name”=>“RailsConf”, “id”=>“1”}>

users = User.find(:all)
=> [#<User:0xb7620964 @attributes={“name”=>“Bob”, “id”=>“1”}>,
#<User:0xb7620928 @attributes={“name”=>“Joe”, “id”=>“2”}>]

w.presenterships.clear
=> []

w.presenterships.create :user_id => users[0].id
=> #<Presentership:0xb760c428
@errors=#<ActiveRecord::Errors:0xb760b898 @errors={},
@base=#<Presentership:0xb760c428 …>>, @attributes={“workshop_id”=>1,
“id”=>5, “user_id”=>1}, @new_record=false>

w.presenterships.create :user => users[1]
=> #<Presentership:0xb76066e0
@errors=#<ActiveRecord::Errors:0xb7605da8 @errors={},
@base=#<Presentership:0xb76066e0 …>>, @attributes={“workshop_id”=>1,
“id”=>6, “user_id”=>2}, @new_record=false, @user=#<User:0xb7620928
@attributes={“name”=>“Joe”, “id”=>“2”}>>

w.presenterships
=> [#<Presentership:0xb760c428
@errors=#<ActiveRecord::Errors:0xb760b898 @errors={},
@base=#<Presentership:0xb760c428 …>>, @attributes={“workshop_id”=>1,
“id”=>5, “user_id”=>1}, @new_record=false>, #<Presentership:0xb76066e0
@errors=#<ActiveRecord::Errors:0xb7605da8 @errors={},
@base=#<Presentership:0xb76066e0 …>>, @attributes={“workshop_id”=>1,
“id”=>6, “user_id”=>2}, @new_record=false, @user=#<User:0xb7620928
@attributes={“name”=>“Joe”, “id”=>“2”}>>]

w.presenters true
=> [#<User:0xb75ff8e0 @attributes={“name”=>“Bob”, “id”=>“1”}>,
#<User:0xb75ff8b8 @attributes={“name”=>“Joe”, “id”=>“2”}>]


#6

On 2/8/07, Brian H. removed_email_address@domain.invalid wrote:

I was afraid it was something I did, and looks like I was right.

I don’t think it’s something you did. Check the thread titled
“AssociationTypeMismatch:
RoleType expected, got RoleType”
I’m having the same problem and I haven’t changed anything…only
upgraded
Rails. I think the reason these guys weren’t able to repeat is that it
always works the first time you restart your server, but after that it’s
broken. Wondering if someone has filed this as an official bug…

Jake