Rails 3.1自定义控制器和视图具有默认值

时间:2011-11-30 07:28:56

标签: ruby-on-rails ruby-on-rails-3.1

背景:

  • 我正在构建一个允许用户创建自己网站的应用(例如mywebsite.alexlod.com)
  • 每个网站所有者都隶属于我,所以我相信他们会写自己的rails代码
  • 每个网站都应该有默认控制器和视图,除非其中一个所有者创建了自己的

以下是我设想控制器工作的方式:

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

让我举个例子。假设我的一位网站所有者(foo.alexlod.com)想要调整app/controllers/photos_controller.rb。他们应该能够创建foo/controllers/photos_controller.rb,从而使用他们的控制器而不是默认控制器。我认为这里的正确方法与路由和加载路径有关,但我是Rails和Ruby的新手,可以使用一些指导。

至于观点,我希望他们的工作方式大致相同。在<subdomain>/views/中定义视图或部分视图时,将使用该视图而不是app/views/中的默认视图。

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

2 个答案:

答案 0 :(得分:0)

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

现在,您只需确定每个请求加载哪个引擎。这就是我认为可能阻碍你的想法的部分 - 你不想在生产中一直装载和卸载代码。

在这种情况下,您可能希望选择Liquid这样的模板语言。但是,这对用户的控制要少得多。

答案 1 :(得分:0)

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

以下是我为观点所做的事情:

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_controller_path方法等同于prepend_view_path。老实说,我不知道如何处理这个问题,你可以使用你的case语句方法,或者可能动态地将请求转发给子域控制器(如果存在的话)。我认为可以在控制器中添加一个before_filter来评估每个请求,就像我在上面显示视图一样,然后确定应该使用哪个控制器。

我也偶然发现了这个问题:Rails 3.1 load controller from different path based on subdomain,不确定它是否对您有所帮助。