判断控制器是否在Rails 3中的嵌套路由中使用

时间:2010-11-08 00:46:33

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

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

resources :companies do
   resources :projects
end

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

2 个答案:

答案 0 :(得分:10)

我会改变你的发现范围。 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

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

现在,只要您引用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>

根据需要进行修改。

希望这有用。

答案 1 :(得分:1)

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

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