1

我有这样的东西

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

但这并不酷,我认为:)

4

1 回答 1

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

这应该使用适当的类创建回复。此时方法应该按需要工作。

于 2010-08-20T16:53:32.780 回答