Rails STI: вызов дочернего метода - PullRequest
1 голос
/ 20 августа 2010

У меня есть что-то вроде этого

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

Но это не круто, я думаю:)

1 Ответ

2 голосов
/ 20 августа 2010

Когда вы имеете дело с моделями на основе ИППП, у вас будут проблемы с их созданием, если вы не будете осторожны. Их получение должно выполняться автоматически, если вы используете базовый класс для поиска.

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

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])

Это должно создать ответ с соответствующим классом. На этом этапе методы должны работать как нужно.

...