开发者

Tell if a controller is being used in a nested route in Rails 3

I made a nested r开发者_开发问答oute in a Ruby on Rails 3 project. with the following routing:

resources :companies do
   resources :projects
end

now I can get to the project contoller's index method via example.com/projects/id or example.com/companies/id/projects/id, but both pages display exactly in the same manner. How can I change the projects page in the second example to only show projects that are associated with that company?


I would change how you scope the finds. Rails 3 is beautiful for allowing you to do this because just about everything is scope'able.

Firstly in your controller I would find the parent resource using something like this:

before_filter :find_company

# your actions go here

private

  def find_company
    @company = Company.find(params[:company_id]) if params[:company_id]
  end

This should be fairly straight forward: Find a Company record that has an ID that matches the one passed in from the nested route. If it's not nested, then there's not going to be a params[:company_id] so therefore there wouldn't be a @company variable set.

Next, you want to scope the project find, depending on whether or not a @company is set. This is easy too. Right under the first before_filter, put this one:

before_filter :scope_projects

Then define the method for it underneath the find_company method like this:

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

Now you're probably thinking "WOAH". I know. Me too.

Now wherever you would reference either the projects association or the Project class, use @projects instead. By the power of this scope_projects method, your app will know whether or not you mean "all projects, ever" or "all projects, ever, that are in the specified company".

Now when you get to the views, you could do something like this:

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

You could even move it into a helper:

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

And turn that ugly hunk-o-logic into this:

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

Modify as required.

Hope this has been helpful.


With the power of inherited_resources you can have optional nesting with the following controller:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜