Вопрос

I have a STI table (Vote) with many children (Tag::Vote, User::Vote, Group::Vote, etc). All the children classes share a very similar method that looks like this:

def self.cast_vote(params)
  value = params[:value]
  vote = Tag::Vote.where(:user_id => User.current.id,
    :voteable_type => params[:voteable_type],
    :voteable_id => params[:voteable_id]).first_or_create(:value => value)
  Vote.create_update_or_destroy_vote(vote, value)
end

The only difference from one class to the next is in the second line, when I refer to the child's class name:

vote = Tag::Vote.where. . . .

I would like to refactor this method into the parent class. It almost works when I replace the second line with:

vote = self.where. . . .

The problem here is that self refers to Vote, rather than Tag::Vote or User::Vote. In turn, the type column (which Rails autofills with a child's class name) gets set to nil, since it's coming from Vote rather than one of the children.

Is there a way for a child class to inherit this method and call itself, rather than its parent?

Это было полезно?

Решение

I don't think you can avoid having some knowledge of the specific subclass if you want the type set correctly, however you could streamline the code so there is far less code duplication. Something like:

class Vote
  def self.cast_vote_of_type(params, subtype)
     ....first_or_create(value: value, type: subtype)
  end
end

class Tag::Vote
  def self.cast_vote(params)
    cast_vote_of_type(params, self.class.name)
  end
end
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top