Plugin to copy data from related has_one model

Hi, this is my first post, so nice to meet you all and thanks in
advance for your help.

I have a “task” model that has it’s own CRUD interface, and can get
“promoted” to another model, that is, it gets associated with a new
record of another model. In the new form for the new model I want to
prepopulate the fields that both models share so the user doesn’t have
to copy them. I did this with the following code:

class Task < ActiveRecord::Base
belongs_to :entity, :polymorphic => true
end

…and…

class Issue < ActiveRecord::Base
  has_one :task, :as => "entity"

  alias_method :set_task=, :task=
  def task=(t)
    task = Task.find(t) if t.class != Task
    self.set_task = t
    copy_task_attributes
  end

 def copy_task_attributes
   shared_attributes = self.task.attributes.reject do |attribute,

value|
!self.attributes.has_key? attribute
end
self.attributes = shared_attributes
end
end

This works, if I create a new Issue:

@issue = Issue.new :task => Task.find(params[:task])

It inherits the common attributes.

The problem arises when I want to put all that logic into a plugin:

module ActiveRecord
  module Acts
    module Taskable # need to change the name
      def self.included(base)
        base.extend(ClassMethods)
      end

      module ClassMethods
        def acts_as_taskable
         has_one :task, :as => "entity"
         alias_method :set_task=, :task=
         include InstanceMethods
       end
     end

     module InstanceMethods

       def task=(t)
         task = Task.find(t) if t.class != Task
         self.set_task = t
         copy_task_attributes
       end

       def copy_task_attributes
         shared_attributes = self.task.attributes.reject do |

attribute, value|
!self.attributes.has_key? attribute
end
self.attributes = shared_attributes
end

     end
   end
 end

end

Then if I do:

class Issue < ActiveRecord::Base
  acts_as_taskable
end

It doesn’t pass the tests (the new record does not inherit the
attributes).

Does anyone knows why this happens? Or better yet, what’s the correct
way of doing this? (I can’t stop thinking that rails already has this
functionality and I can’t find it)

Thanks. Lucas.

On 19 Jun 2008, at 00:19, [email protected] wrote:

Then if I do:

class Issue < ActiveRecord::Base
acts_as_taskable
end

you need to include your module in Issue (or in ActiveRecord::Base)
and I can’t see you doing that anywhere (although if you didn’t do
that then the call to acts_as_taskable would raise an unknown method
error). If you’re feeling paranoid, check that the include
InstanceMethods is picking up the right instance methods module ( you
can make sure by expliciting it, ie
ActiveRecord::Acts::Taskable::InstanceMethods

Fred

On 19 jun, 06:46, Frederick C. [email protected] wrote:

you need to include your module in Issue (or in ActiveRecord::Base)
and I can’t see you doing that anywhere (although if you didn’t do
that then the call to acts_as_taskable would raise an unknown method
error). If you’re feeling paranoid, check that the include
InstanceMethods is picking up the right instance methods module ( you
can make sure by expliciting it, ie
ActiveRecord::Acts::Taskable::InstanceMethods

Thanks for answering, I’m including it in ActiveRecord::Base (via the
init.rb script), at least I thought so. I tryed this:

require “acts_as_taskable”
class Issue < ActiveRecord::Base
extend CatBag::Acts::Taskable::ClassMethods
include CatBag::Acts::Taskable::InstanceMethods
acts_as_taskable
end

And removed the code from init.rb. But the problem remains.

In the console I created a new issue instance and it has the
copy_task_attributes method (and works). I also tryed changing the
name of the new method (in the module) to :task2= (so it doesn’t clash
with the default one), it gets added to the instances and it works
fine.

I’m suspecting that the task= method somehow it’s getting regenerated
by rails at some point. but I don’t know how to check for it.

Also, is this the “correct” way of facing this problem?

Thanks. Lucas.