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.