-1

我有一个名为 Page 的基本模型,并且有许多基于 Page 的 STI 模型,例如

绘画

文章

故事

ETC...

我对每个 STI 模型都有单独的控制器和视图,因为我需要根据模型类型自定义视图层,并且控制器具有不同的逻辑,因此需要单独的控制器。但是,我需要将所有模型的作者字段设置为当前用户。我如何在一个地方做到这一点?

例如,如果我在页面控制器上使用 before_action 并设置作者,它会影响 @page 实例变量,而我的 DrawingsController 正在使用 @drawing,因此除非我在 DrawingsController 中重复相同的代码,否则它不会保存我的 @drawing 的作者。

编辑:

我的控制器层次结构是

绘图控制器 < 页面控制器

页面控制器 < 应用控制器

PagesController 和 DrawingsController 都具有全部 7 个 restful 动作。但是,PagesController 上的操作没有任何用途,因为我不希望我的任何用户创建页面。我只希望他们创建继承的 STI 类,如绘图。

4

2 回答 2

0

您可以在控制器层次结构中使用一些约定和元编程来做到这一点:

def add_author
  model = instance_variable_get(:"@#{controller_name.singularize}")
  model.author = current_user
end
于 2013-11-06T21:29:31.930 回答
0

老实说,我不保证这个答案的“最佳实践”,但无论如何我都会提出它,以防它在某种程度上有所帮助。另请注意,在重新考虑问题后,我意识到我在评论中建议的第一个解决方案是错误的,第二个也不太正确。所以我只发布第二个建议的修改版本:

简短的回答:PagesController处理大部分工作,如果需要,只将模型特定的事情委托给子控制器。正如 phoet 所说,您可以使用一些元编程(以不同的方式)来完成此操作。

class PagesController < ApplicationController
    # pages controller stuff here
    def create
        @page = controller_name.classify.constantize.new(params[:page_params]) # I love Rails, don't you?
        @page.author = current_user
        handle_additional_create_actions 

        # For completeness of this example...
        if @page.save
            # render / redirect on success
        else
            # render errors
        end
    end
protected

    # This method should be overwritten by sub controllers if needed
    # Also, name this whatever you like, this is merely a verbose example for illustration purposes
    def handle_additional_create_actions
        # in the pages controller, this method does nothing
    end
end

并且,如果特定于模型的控制器需要执行其他操作:

class DrawingsController < PagesController
    # drawing controller stuff here

protected
    def handle_additional_create_actions
        @page.some_other_field = some_other_data
    end
end

快速说明:请注意,在我的建议中,您正在消除特定于模型的变量名称,这意味着我们不再有 an@drawing和 an@article等。您的模型本质上都是Page对象的类型,因此我们将按其通用名称来称呼它作为约定。这样,当您要求DrawingsController为该类做一些特定的事情时Drawing,它知道可以通过我们的通用命名@page对象访问该实例。

因此PagesController,无论您处理的是哪种具体模型类型,最终都会完成繁重的工作。这样,在页面控制器中只能找到一般的页面内容,而在它们各自的具体控制器中可以找到绘图、文章或故事特定的内容。

于 2013-11-08T16:21:50.777 回答