Preacher
Preacher

Reputation: 2420

How can I perform a callback on multiple fields without repeating myself?

I have the following before_save callback:

  def clear_unused_parents
    if self.parent_type == 'global'
      self.sport_id = nil
      self.school_id = nil
      self.team_id = nil
    elsif self.parent_type == 'sport'
      self.school_id = nil
      self.team_id = nil
    elsif self.parent_type == 'school'
      self.sport_id = nil
      self.team_id = nil
    elsif self.parent_type == 'team'
      self.sport_id = nil      
      self.school_id = nil
    end
  end

Essentially, I have an Advertisement model that can either be global or belong to a sport, school, or team. The above code works to set the id field to NULL on all but the appropriate field. How can I write the same thing without repeating myself so much?

I'd like to write something like this, but I'm unsure how to do it.

  def clear_unused_parents
    parent_type = self.parent_type
    parent_fields = ['sport_id', 'school_id', 'team_id']
    parent_fields.each do |parent_field|
      unless parent_field == parent_type
        parent_field = nil
      end
    end
  end

Upvotes: 0

Views: 140

Answers (3)

Sean Hill
Sean Hill

Reputation: 15056

Without testing it out, I think you should be able to do something like this:

def clear_unused_parents
        parent_type = self.parent_type
        parent_fields = ['sport_id', 'school_id', 'team_id']
        parent_fields.each do |parent_field|
          unless parent_field == parent_type + "_id"
            write_attribute(parent_field.to_sym, nil)
          end
        end
      end

Upvotes: 1

Xavier Holt
Xavier Holt

Reputation: 14619

You should be able to do this with the send method (calling MyClass.send('foo', args) is essentially equivalent to calling MyClass.foo(args)):

TYPES = ['global', 'sport', 'school', 'team']

def clear_unused_parents
    TYPES.each do |attr|
        self.send("#{attr}_id=", nil) if attr != self.parent_type
    end
end

Hope that helps!

PS: Judging by your example, there might be a better way to do this. Take a look at Polymorphic Associations - I've never been a huge fan myself, but they might be just what you're looking for...

Upvotes: 2

macarthy
macarthy

Reputation: 3069

Think you are looking for

write_attribute(parent_field,nil)

Upvotes: 1

Related Questions