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.

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

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.