У меня есть что-то вроде этого
class Reply < AR::Base
end
class VideoReply < Reply
def hello
p 'not ok'
end
end
class PostReply < Reply
def hello
p 'ok'
end
end
...
Итак, когда я создаю объект:
# params[:reply][:type] = "VideoReply"
@reply = Reply.new(params[:reply])
Как я могу вызвать дочерний метод (в данном случае VideoReply :: hello
)
UPD: Я могу представить себе только очень глупое решение:
@reply = Reply.new(params[:reply])
eval(@reply.type).find(@reply.id).hello
Но это не круто, я думаю:)
Когда вы имеете дело с моделями на основе STI, у вас будут проблемы с их созданием, если вы не будете осторожны. Их получение должно выполняться автоматически, если для поиска вы используете базовый класс.
В первую очередь вам нужно создать подходящую модель, а все остальное будет в порядке. В вашей модели или контроллере определите список допустимых классов:
REPLY_CLASSES = %w[ Reply VideoReply PostReply ]
Затем вы можете использовать это для проверки типа перед созданием объекта:
# Find the type in the list of valid classes, or default to the first
# entry if not found.
reply_class = REPLY_CLASSES[REPLY_CLASSES.index(params[:reply][:type]).to_i]
# Convert this string into a class and build a new record
@reply = reply_class.constantize.new(params[:reply])
Это должно создать ответ с правильным классом. На этом этапе методы должны работать должным образом.