2013-04-22 3 views
0

У меня есть стол 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 autofills с именем дочернего класса) устанавливается в нуль, поскольку он исходит от Vote, а не одного из детей.

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

ответ

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 
+0

Это определенное улучшение. – nullnullnull