0

This one is driving me crazy. I've got a nested relationship between two models in my project, and I decided I did not want it to be shallow, since the child object (years) has no meaning outside the context of the parent (festivals).

So I sort of de-shallowed the relationship wherever I could find a reference to it, but I find myself unable to access the page to create a new child object.

Here's the url as I understand it should be: /festivals/1/years/new

from routes.rb:

resources :festivals do
   resources :years
end

From years_controller.rb:

# GET festivals/1/years/new
# GET festivals/1/years/new.json
def new
  @festival = Festival.find(params[:festival_id])
  @year = @festival.years.build

  respond_to do |format|
    format.html # new.html.erb
    format.json { render :json => @year }
  end
end

And the button users press to get to the New page (on the Show page for the parent object):

<%= link_to 'Add Year', new_festival_year_path(@festival), :class => 'btn' %>

That takes the user to the correct URL, but I get:

No route matches {:action=>"show", :controller=>"years", :festival_id=>#<Festival id: 7, name: "Improganza", founded: nil, logo: "", mission: "This is that one that people spend a lot of money t...", city: "Honolulu", state_code: "HI", country_code: "US", created_at: "2013-07-26 14:49:19", updated_at: "2013-07-26 14:49:19">}

I created a new Rails project and set up scaffolds using Akria Matsuda's nested_scaffold gem, just to compare that output with my code... the resulting files look as I've shown here. I have no idea what I might be missing.

Just for good measure, the output of my rake routes:

            festival_years GET        /festivals/:festival_id/years(.:format)          years#index
                           POST       /festivals/:festival_id/years(.:format)          years#create
         new_festival_year GET        /festivals/:festival_id/years/new(.:format)      years#new
        edit_festival_year GET        /festivals/:festival_id/years/:id/edit(.:format) years#edit
             festival_year GET        /festivals/:festival_id/years/:id(.:format)      years#show
                           PUT        /festivals/:festival_id/years/:id(.:format)      years#update
                           DELETE     /festivals/:festival_id/years/:id(.:format)      years#destroy
                 festivals GET        /festivals(.:format)                             festivals#index
                           POST       /festivals(.:format)                             festivals#create
              new_festival GET        /festivals/new(.:format)                         festivals#new
             edit_festival GET        /festivals/:id/edit(.:format)                    festivals#edit
                  festival GET        /festivals/:id(.:format)                         festivals#show
                           PUT        /festivals/:id(.:format)                         festivals#update
                           DELETE     /festivals/:id(.:format)                         festivals#destroy
                           GET        /festivals(.:format)                             festivals#index
                           POST       /festivals(.:format)                             festivals#create
                           GET        /festivals/new(.:format)                         festivals#new
                           GET        /festivals/:id/edit(.:format)                    festivals#edit
                           GET        /festivals/:id(.:format)                         festivals#show
                           PUT        /festivals/:id(.:format)                         festivals#update
                           DELETE     /festivals/:id(.:format)                         festivals#destroy

3 Answers3

1

Try this:

<%= link_to 'Add Year', new_festival_year_path(@festival.id, :class => 'btn' %>    

or

<%= link_to 'Add Year', new_festival_year_path({festival_id: @festival.id}, :class => 'btn' %>

according to the error you're getting

:festival_id=>#<Festival id: 7, name: "Improganza", founded: nil, logo: "", mission: "This is that one that people spend a lot of money t...", city: "Honolulu", state_code: "HI", country_code: "US", created_at: "2013-07-26 14:49:19", updated_at: "2013-07-26 14:49:19">}

the router is getting your whole festival param as the input for :festival_id

dax
  • 10,779
  • 8
  • 51
  • 86
  • Thanks, but that turns out not to be it... in fact, the same exception happens if I don't use the "Add Year" link but instead go to `/festivals/1/years/new' directly! – monkeyangst Jul 30 '13 at 21:32
  • do you mean in the view? I don't think that will help, as it gives the same error if I just go to the URL directly. But I'll try it. – monkeyangst Jul 30 '13 at 21:53
  • Actually, @dax, that breaks the view. – monkeyangst Jul 30 '13 at 21:55
0

I think you are merging together the #new and #year actions in the years_controller and that might be causing some problems.

# GET festivals/1/years/new
# GET festivals/1/years/new.json
def new
  @festival = Festival.find(params[:festival_id])
  @year = @festival.years.build
end

def create
  @festival = Festival.find(params[:festival_id])
  @year = @festival.years.create(...)
  #...fill in the rest of the method...
end

You also should update your link:

<%= link_to 'Add Year', new_festival_year_path(festival_id: @festival), :class => 'btn' %>

I created a short quiz on nested resources that might be helpful.

Powers
  • 18,150
  • 10
  • 103
  • 108
  • That turned out not to be it either. And the #create action actually already looked as you have it. – monkeyangst Jul 30 '13 at 21:36
  • UPDATE: I discovered the problem is in a view rather than the controller, specifically the _form.html.erb partial. I should now be able to narrow down exactly where. Thanks, everyone, for your help. – monkeyangst Jul 30 '13 at 22:00
0

The answer was fairly silly. In my Rails server log (which I need to train myself to pay more attention to), I saw the some lines indicating a problem in line 63 of my _form.html.erb partial.

That line was:

<%= link_to t('.cancel', :default => t("helpers.links.cancel")),
   festival_year_path(@festival), :class => 'btn' %>

Oops. Why I ever decided the "Cancel" button should take you to a year (that, of course, would not exist) is beyond me. I changed it to festival_path(@festival) and it's all good.

Thanks, everyone, for your help. I'm a newcomer to StackOverflow and to Rails in general. It really makes me feel welcome that I got such quick responses!