mark j. hughes
2006-Sep-28 01:44 UTC
Mapping external objects locally to arbitrarily named columns
Hi all,
I''m working on an app where I have a simplified set up like this:
--
create_table :tasks do |t|
t.column :subject, :string
t.column :description, :string
t.column :requester, :integer
t.column :assignee, :integer
end
create_table :users do |t|
t.column :name, :string
end
--
class User < ActiveRecord:Base
end
class Task < ActiveRecord::Base
composed_of :requester, :class_name => ''User'', :mapping
=> [ [
:requester, :id ] ]
composed_of :assignee, :class_name => ''User'', :mapping
=> [ [
:assignee, :id ] ]
end
--
This is a common pattern we use through many of our apps to track users
and the roles they fill. Each role is guaranteed to have only one user
fit it at any one time, but any user may fit a role in multiple Tasks.
--------
I was hoping that composed_of was the magic bullet, but it doesn''t seem
to be. Given the following little script:
user1 = User.create( :name => "John Doe" )
user2 = User.create( :name => "Jane Doe" )
task = Task.create( :subject => "Paint the house", :description
=> "How
about a nice shade of yellow?", :assignee => user1, :requester =>
user2
)
fromdb = Task.find task.id
puts fromdb.assignee
--------
But the output looks like this:
=> #<User:0x26b9b88 @attributes={"name"=>"John
Doe", "id"=>1},
@new_record=false, @errors=#<ActiveRecord::Errors:0x26b73d8 @errors={},
@base=#<User:0x26b9b88 ...>>>>> user2=User.create( :name => "Jane Doe" )
=> #<User:0x26a190c @attributes={"name"=>"Jane
Doe", "id"=>2},
@new_record=false, @errors=#<ActiveRecord::Errors:0x26a0df4 @errors={},
@base=#<User:0x26a190c ...>>>>> task=Task.create( :subject => "Paint the house",
:description => "How about a nice shade of yellow?", :assignee
=> user1, :requester => user2 )
=> #<Task:0x2679240 @assignee=#<User:0x26b9b88
@attributes={"name"=>"John Doe", "id"=>1},
@new_record=false,
@errors=#<ActiveRecord::Errors:0x26b73d8 @errors={},
@base=#<User:0x26b9b88 ...>>>, @attributes={"id"=>1,
"subject"=>"Paint
the house", "description"=>"How about a nice shade of
yellow?",
"assignee"=>1, "requester"=>2},
@requester=#<User:0x26a190c
@attributes={"name"=>"Jane Doe", "id"=>2},
@new_record=false,
@errors=#<ActiveRecord::Errors:0x26a0df4 @errors={},
@base=#<User:0x26a190c ...>>>, @new_record=false,
@errors=#<ActiveRecord::Errors:0x266c6e4 @errors={},
@base=#<Task:0x2679240 ...>>>>> fromdb=Task.find task.id
=> #<Task:0x26510ec @attributes={"subject"=>"Paint the
house",
"id"=>"1", "description"=>"How about a
nice shade of yellow?",
"assignee"=>"1",
"requester"=>"2"}>>> puts fromdb.assignee
TypeError: can''t dup Fixnum
from
/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/base.rb:1505:in
`dup''
from
/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/base.rb:1505:in
`attributes=''
from
/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/base.rb:1354:in
`initialize_without_callbacks''
from
/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/callbacks.rb:236:in
`initialize''
from (eval):3:in `new''
from (eval):3:in `assignee''
from (irb):7
--------
At first glance, it seems clear I have done something completely wrong,
and that composed_of isn''t for me in this instance. I''m hoping
I just
have a typo, but I don''t think I do...
So I was hoping someone could point me in the direction of the
"correct" way of doing this? I use this particular pattern in many
places, and I''m wondering if I really have to implement this style of
accessor/mutator everywhere I do (assuming I renamed the two db columns
to requester/assignee_user_id):
def requester
return User.find( @requester_user_id )
end
def requester=(requester)
user = User.find( requester.id )
if user
@requester_user_id = user.id
end
end
def assignee
return User.find( @assignee_user_id )
end
def assignee=(assignee)
user = User.find( assignee.id )
if user
@assignee_user_id = user.id
end
end
Any help would be much appreciated. Thanks!
-- mark
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk
-~----------~----~----~----~------~----~------~--~---
Maxim Kulkin
2006-Sep-28 04:43 UTC
Re: Mapping external objects locally to arbitrarily named columns
mark j. hughes ïèøåò:> class User < ActiveRecord:Base > end > > class Task < ActiveRecord::Base > composed_of :requester, :class_name => ''User'', :mapping => [ [ > :requester, :id ] ] > composed_of :assignee, :class_name => ''User'', :mapping => [ [ > :assignee, :id ] ] > end >class Task < ActiveRecord::Base belongs_to :requester, :class_name => ''User'', :foreign_key => ''requester'' belongs_to :assignee, :class_name => ''User'', :foreign_key => ''assignee'' end You can RDoc everything else. I also suggest you to rename columns to requester_id and assignee_id. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk -~----------~----~----~----~------~----~------~--~---
mark j. hughes
2006-Sep-28 18:32 UTC
Re: Mapping external objects locally to arbitrarily named columns
Wow. How embarassing... Thanks for your reply, Maxim. Ex post facto, it makes total sense, but it just didn''t appear intuitive that the foreign_key is actually the local key, since belongs_to is defining a backwards relationship from another object/table. Thanks so much! --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk -~----------~----~----~----~------~----~------~--~---