Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I made a nested route 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?

like image 432
GSto Avatar asked Dec 21 '22 21:12

GSto


1 Answers

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.

like image 120
Ryan Bigg Avatar answered Apr 29 '23 02:04

Ryan Bigg