I''ve been using polymorphic joins from edge rails based on about 5
lines
of advice Rick Olson gave me over IRC. There''s some sparse
documentation
popping up but it seems to cover a somewhat different case.
Anyway - I pretty much got it to work - save for one detail. Here''s
what
I have:
class Event < ActiveRecord::Base
belongs_to :attachable, :polymorphic => true
#events table has attachable_type and attachable_id fields
end
class Task < ActiveRecord::Base
has_many :events, :as => :attachable
#tasks tables is nothing special
end
and now a unit test:
#there''s some fixtures above
def test_polymorphics
assert tasks(:simple_task).events << events(:simple_event_1)
assert tasks(:simple_task).events << events(:simple_event_2)
assert events(:simple_event_1).save!
assert tasks(:simple_task).save!
assert_equal 2, tasks(:simple_task).events.size
assert_equal "simple event 1",
tasks(:simple_task).events.find(1).note
assert_equal "simple task", events(:simple_event_1).task.title
end
All asserts pass except the last one:
ruby test/unit/task_test.rb
Loaded suite test/unit/task_test
Started
E.
Finished in 1.103896 seconds.
1) Error:
test_polymorphics(TaskTest):
NoMethodError: undefined method `task'' for #<Event:0x22258a0>
_RAILS_ROOT_/config/../vendor/rails/activerecord/lib/active_record/base.rb:1565:in
`method_missing''
test/unit/task_test.rb:17:in `test_polymorphics''
2 tests, 7 assertions, 0 failures, 1 errors
(path replaced with RAILS_ROOT since I''m secretive like that)
In other words - I can do stuff like @task.events << @event but NOT
@event.task = @task ! (or indeed @event.task.* ) @tasks.events <<
definitely works - I even checked the db and the attachment_type/id
fields are set exactly as expected.
It kind of makes sense - since I never actually mention :tasks anywhere
in Event''s model definition. But how exactly do I mention it?
I looked over the example in the wiki but it doesn''t seem to touch on
this problem at all (and it kind of tries to do something different too)
- SO - any help is apretiated.
It could also be that this particular piece of functionality simply
hasn''t been implemented yet...
--
Posted via http://www.ruby-forum.com/.
Rick Olson
2006-Feb-15 05:16 UTC
[Rails] Polymorphic joins work one way, but not the other
> In other words - I can do stuff like @task.events << @event but NOT > @event.task = @task ! (or indeed @event.task.* ) @tasks.events << > definitely works - I even checked the db and the attachment_type/id > fields are set exactly as expected.Try this: class Event < ActiveRecord::Base belongs_to :attachable, :polymorphic => true def task=(task) self.attachable = task end end If you have a lot of properties, you can earn points towards your metaprogramming merit badge: class Event < ActiveRecord::Base belongs_to :attachable, :polymorphic => true %w(task project stuff).each do |model| define_method("#{model}=") do |value| self.attachable = value end end end -- Rick Olson http://techno-weenie.net
rubyruy
2006-Feb-15 06:57 UTC
[Rails] Re: Polymorphic joins work one way, but not the other
Oh my! So it isn''t implemented! Are there plans to do so later? The way you mention only adds the = method right? It won''t add all of task''s methods proper from what I can tell. It would be nice to rework the syntax for the new polymorphic stuff a little. It''s a complicated concept, sure, but it''s really a lot less approachable then the rest of AR-magic. Here''s what I''d like. class Comment < AR:B belongs_to :page, :or => :file, :or => :thing. :or => :other_thing, :as => :attachable end It isn''t quite as elegant (since there would have to be an ''implied'' :or => before :page and :as is actually changing behavior from has_many) but it would be far more easy to understand imho. Rick Olson wrote:>> In other words - I can do stuff like @task.events << @event but NOT >> @event.task = @task ! (or indeed @event.task.* ) @tasks.events << >> definitely works - I even checked the db and the attachment_type/id >> fields are set exactly as expected. > > Try this: > > class Event < ActiveRecord::Base > belongs_to :attachable, :polymorphic => true > > def task=(task) > self.attachable = task > end > end > > If you have a lot of properties, you can earn points towards your > metaprogramming merit badge: > > class Event < ActiveRecord::Base > belongs_to :attachable, :polymorphic => true > > %w(task project stuff).each do |model| > define_method("#{model}=") do |value| > self.attachable = value > end > end > end > > -- > Rick Olson > http://techno-weenie.net-- Posted via http://www.ruby-forum.com/.