【问题标题】:Tell if a controller is being used in a nested route in Rails 3判断控制器是否在 Rails 3 的嵌套路由中使用
【发布时间】:2010-11-08 00:46:33
【问题描述】:

我在 Ruby on Rails 3 项目中创建了一个嵌套路由。使用以下路由:

resources :companies do
   resources :projects
end

现在我可以通过 example.com/projects/id 或 example.com/companies/id/projects/id 访问项目控制器的索引方法,但两个页面的显示方式完全相同。如何更改第二个示例中的项目页面以仅显示与该公司关联的项目?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 routing


    【解决方案1】:

    我会更改您查找结果的范围。 Rails 3 很漂亮,因为它允许您这样做,因为几乎所有东西都是可作用域的。

    首先在你的控制器中,我会使用这样的东西找到父资源:

    before_filter :find_company
    
    # your actions go here
    
    private
    
      def find_company
        @company = Company.find(params[:company_id]) if params[:company_id]
      end
    

    这应该是相当直接的:找到一个Company 记录,其 ID 与从嵌套路由传入的 ID 匹配。如果它没有嵌套,则不会有 params[:company_id],因此不会有 @company 变量集。

    接下来,您要根据是否设置@company 来确定项目查找范围。这也很容易。在第一个before_filter下面,放这个:

    before_filter :scope_projects
    

    然后在find_company 方法下面定义它的方法,如下所示:

    def scope_projects
      @projects = @company ? @company.projects : Project
    end
    

    现在你可能在想“哇”。我知道。我也是。

    现在,无论您要引用 projects 关联还是 Project 类,请改用 @projects。借助 scope_projects 方法的强大功能,您的应用将知道您的意思是“所有项目,永远”还是“所有项目,永远,在指定公司”。

    现在,当您到达视图时,您可以执行以下操作:

    <h1><% if @company %><%= @company.name %>'s<% end %> Projects</h1>
    

    你甚至可以把它移到一个助手中:

    def optional_company
      if @company
        @company.name + "'s"
      end
    end
    

    然后把那个丑陋的大块头逻辑变成这样:

    <h1><%= optional_company %> Projects</h1>
    

    根据需要修改。

    希望这对您有所帮助。

    【讨论】:

      【解决方案2】:

      借助inherited_resources 的强大功能,您可以使用以下控制器进行可选嵌套:

      class ProjectsController < InheritedResources::Base
        belongs_to :company, :optional => true
      end 
      

      【讨论】:

        猜你喜欢
        • 2011-07-27
        • 1970-01-01
        • 2015-10-05
        • 1970-01-01
        • 2017-02-12
        • 1970-01-01
        • 2011-09-07
        • 2019-12-12
        • 1970-01-01
        相关资源
        最近更新 更多