Ruby on rails Rails 3.1自定义控制器和视图,带默认值

Ruby on rails Rails 3.1自定义控制器和视图,带默认值,ruby-on-rails,ruby-on-rails-3.1,Ruby On Rails,Ruby On Rails 3.1,背景: 我正在开发一个应用程序,允许用户创建自己的网站(例如mywebsite.alexlod.com) 每个网站所有者都与我有关联,所以我相信他们会编写自己的rails代码 每个网站都应该有默认的控制器和视图,除非其中一个所有者创建了自己的控制器和视图 以下是我对控制器工作的设想: 我认为app/controllers/中的内容将是默认内容,但是当在顶级目录中指定文件时,该文件将优先于默认内容 让我举个例子。比如说,我的一个网站所有者(foo.alexlod.com)想要调整app/con

背景:

  • 我正在开发一个应用程序,允许用户创建自己的网站(例如mywebsite.alexlod.com)
  • 每个网站所有者都与我有关联,所以我相信他们会编写自己的rails代码
  • 每个网站都应该有默认的控制器和视图,除非其中一个所有者创建了自己的控制器和视图
以下是我对控制器工作的设想:

我认为
app/controllers/
中的内容将是默认内容,但是当在
顶级目录中指定文件时,该文件将优先于默认内容

让我举个例子。比如说,我的一个网站所有者(foo.alexlod.com)想要调整
app/controllers/photos\u controller.rb
。他们应该能够创建
foo/controllers/photos\u controller.rb
,从而使用他们的控制器而不是默认控制器。我认为这里的正确方法与路由和加载路径有关,但我对Rails和Ruby不熟悉,需要一些指导

至于意见方面,我希望它们的作用大致相同。在
/views/
中定义视图或局部视图时,将使用该视图,而不是
app/views/
中的默认视图

我意识到我的计划违反了默认的rails目录结构。但是这种方法必须比每个控制器动作中的可选case语句更简单。除非有更好的选择?

我相信这可能是你想要的。该链接有点旧,但仍应适用于Rails 3.1。每个子域的控制器和视图都可以放置在各自的引擎文件夹中

现在,您只需要确定每个请求加载哪个引擎。我认为这可能会阻碍您的想法——您不希望在生产过程中一直加载和卸载代码


在这种情况下,您可能需要选择模板语言,如。然而,这给了用户更少的控制权。

我可能有一个部分答案给你,因为听起来你想做一些非常类似于我为我的网站的移动版所做的事情。在我确定用户是移动的之后,我将移动目录添加到路径中,以覆盖我为移动优化的任何视图。如果视图在移动目录中不存在,则默认为默认视图

以下是我对视图所做的操作:

在app/controllers/application_controller.rb中

before_filter :prepend_view_path_if_subdomain

def prepend_view_path_if_subdomain
  unless pSubdomains.blank?
    subdomain = request.subdomain.first

    #This will add the subdomain view directory to the view path before the default
    #Rails view directory and any views here will be picked up and rendered.
    prepend_view_path 'app/' + subdomain + '/views'
  end
end
然而,由于路由的原因,对控制器执行同样的操作有点棘手。没有与prepend_view_path等效的prepend_controller_path方法。老实说,我不知道如何处理这个问题,您可以使用您的case语句方法,或者可能动态地将请求转发给子域控制器(如果存在的话)。我认为有可能在控制器中添加一个before_过滤器,该过滤器对每个请求进行评估,就像我在上面用视图显示的那样,然后确定应该使用哪个控制器


我还偶然发现了这个问题:,不确定它是否对你有帮助。

谢谢,杰夫!我听从雷蒙的建议,检查了引擎。我希望引擎能够很好地使用prepend\u view\u path方法。引擎处理控制器和路由,前置视图路径将处理视图。酷:)。谢谢你,雷蒙。这个解决方案运行得很好,在Jeff的建议下,我也能很好地处理视图。@alexlod您最终是如何(动态地)为每个子域加载一个引擎的?我很想看看你的解决方案。@Jimmy,我不认为你不能动态加载引擎。因此,我加载了每个引擎并添加了路由,以便在给定特定子域的情况下使用适当的控制器。