我有类似的东西
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
但我认为这并不酷!)
答案 0 :(得分:2)
当您处理基于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])
这应该使用适当的类创建回复。此时方法应该按照需要工作。