我在Ruby on Rails 3项目中创建了一个嵌套路由。使用以下路由:
resources :companies do
resources :projects
end
现在我可以通过example.com/projects/id或example.com/companies/id/projects/id查看项目控制器的索引方法,但两个页面都以完全相同的方式显示。如何在第二个示例中更改项目页面以仅显示与该公司关联的项目?
答案 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