Rails STI:调用子方法

发布于 2024-09-15 15:55:11 字数 544 浏览 5 评论 0原文

我有这样的东西

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

但这并不酷,我认为:)

I've got something like this

class Reply < AR::Base
end

class VideoReply < Reply
  def hello
    p 'not ok'
  end
end

class PostReply < Reply
  def hello
    p 'ok'
  end
end

...

So when I am creating object:

# params[:reply][:type] = "VideoReply"
@reply = Reply.new(params[:reply])

How can I invoke child method (in this case VideoReply::hello)?

UPD:
I can imagine only very stupid solution:

@reply = Reply.new(params[:reply])
eval(@reply.type).find(@reply.id).hello

But it is not cool, I think :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

花桑 2024-09-22 15:55:11

当您处理基于 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])

这应该创建具有正确类的回复。此时方法应该按预期工作。

When you're dealing with STI-based models, you'll have problems creating them if you're not careful. Retrieving them should be done automatically so long as you use the base class to find.

What you need is to create the proper kind of model in the first place and the rest will be fine. In your model or controller define a list of valid classes:

REPLY_CLASSES = %w[ Reply VideoReply PostReply ]

Then you can use this to verify the type before creating an object:

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

This should create a reply with the proper class. Methods should work as desired at this point.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文