代码之家  ›  专栏  ›  技术社区  ›  fl00r

rails sti:调用子方法

  •  1
  • fl00r  · 技术社区  · 16 年前

    我有这样的东西

    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 回复  |  直到 16 年前
        1
  •  2
  •   tadman    16 年前

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

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

    推荐文章