# Plugin to copy data from related has\_one model

**URL:** <https://www.ruby-forum.com/t/plugin-to-copy-data-from-related-has-one-model/140832>\
**Category:** Rails\
**Created:** [June 19, 2008, 1:20am UTC](https://www.ruby-forum.com/t/plugin-to-copy-data-from-related-has-one-model/140832 "2008-06-19T01:20:29Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [June 19, 2008, 1:20am UTC](https://www.ruby-forum.com/t/plugin-to-copy-data-from-related-has-one-model/140832/1 "2008-06-19T01:20:29Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [June 19, 2008, 11:47am UTC](https://www.ruby-forum.com/t/plugin-to-copy-data-from-related-has-one-model/140832/2 "2008-06-19T11:47:36Z")

</div>

On 19 Jun 2008, at 00:19, removed\_email\_address@domain.invalid 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

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [June 19, 2008, 3:53pm UTC](https://www.ruby-forum.com/t/plugin-to-copy-data-from-related-has-one-model/140832/3 "2008-06-19T15:53:13Z")

</div>

On 19 jun, 06:46, Frederick C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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.
