Rails: получить имя класса дочернего класса в методе родительского класса

У меня есть таблица STI (Vote) со многими детьми (Tag::Vote, User::Vote, Group::Vote и т. д.). Все дочерние классы используют очень похожий метод, который выглядит следующим образом:

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

Единственная разница от одного класса к другому заключается во второй строке, когда я ссылаюсь на имя дочернего класса:

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

Я хотел бы реорганизовать этот метод в родительский класс. Это почти работает, когда я заменяю вторую строку на:

vote = self.where. . . .

Проблема здесь в том, что self относится к Vote, а не к Tag::Vote или User::Vote. В свою очередь, столбец type (который Rails автоматически заполняет именем дочернего класса) устанавливается равным nil, поскольку он исходит от Vote, а не от одного из дочерних элементов.

Есть ли способ, чтобы дочерний класс наследовал этот метод и вызывал сам себя, а не своего родителя?


person nullnullnull    schedule 22.04.2013    source источник


Ответы (1)


Я не думаю, что вы можете избежать некоторых знаний о конкретном подклассе, если хотите, чтобы тип был установлен правильно, однако вы могли бы упростить код, чтобы было гораздо меньше дублирования кода. Что-то типа:

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
person GSP    schedule 22.04.2013
comment
Это определенное улучшение. - person nullnullnull; 22.04.2013