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', 's开发者_StackOverflow社区chool_id', 'team_id']
parent_fields.each do |parent_field|
unless parent_field == parent_type
parent_field = nil
end
end
end
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...
Think you are looking for
write_attribute(parent_field,nil)
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
精彩评论