Search code examples
ruby-on-railsoverridingsetterbelongs-to

Rails 4 Override belongs_to setter


I am having an issue overriding a setter on a belongs_to attribute. I have the following:

class Task < ActiveRecord::Base
belongs_to :parent_task, :class_name => 'Task', :foreign_key => 'parent_task_id'

def parent_task=(value)
  write_attribute(:parent_task, value)
  unless value == nil
    #remove all groups_belonging_to if this has been made into a child task -i.e. if it has a parent
    self.groups_belonging_to = []
  end
  self.save
end

The user model has many tasks:

class User < ActiveRecord::Base
  has_many :tasks_created_by, class_name: 'Task', foreign_key: 'created_by_id', dependent: :destroy

In my testing I am creating a task like so:

@child_task = @user.tasks_created_by.create!(name: "Task to Delete", parent_task: @top_parent)

Which gives the error:

ActiveModel::MissingAttributeError: can't write unknown attribute `parent_task`

When I remove the override there is no problem, so I am definitely doing the override wrong somehow. I have used very similar override logic elsewhere but not through a relation before.


Solution

  • This would be better written as a callback. You can use a before_save callback to check for a parent_task and if it is set, clear groups_belonging_to:

    class Task < ActiveRecord::Base
      belongs_to :parent_task, class_name: 'Task', foreign_key: 'parent_task_id'
    
      before_save :clear_groups if: :parent_task
    
      def clear_groups
        self.groups_belonging_to = []
      end
    end