I am having trouble using the form_for correctly for my nested resources.
I have the following set up in my models:
team.rb
class Team < ApplicationRecord
has_many :superheroes
accepts_nested_attributes_for :superheroes
end
superhero.rb
class Superhero < ApplicationRecord
belongs_to :team
end
My routes: routes.rb
Rails.application.routes.draw do
root to: 'teams#index'
resources :teams do
resources :superheroes
end
get '/teams/:team_id/superheroes/:id', to: 'superheroes#show', as: 'team_superheros'
end
In '/app/views/superheroes/new.html.erb'
<%= form_for [@team, @superhero] do |f| %>
<p>Name</p>
<p><%= f.text_field :name %></p>
<p>True Identity</p>
<p><%= f.text_field :true_identity %></p>
<p><%= f.submit 'SAVE' %></p>
<% end %>
Lastly, in superheroes_controller.rb
def new
@team = Team.find_by_id(params[:team_id])
@superhero = @team.superheroes.build
end
I think maybe my understanding of the nested form_for isn't correct. When I navigate to the new_superhero page I originally got the following error:
undefined method `team_superheros_path'
So I added the following redirection route to routes.rb:
get '/teams/:team_id/superheroes/:id', to: 'superheroes#show', as: 'team_superheros'
This leaves me with the "Errors: 'ActionController::UrlGenerationError'" message with the specific error:
No route matches {:action=>"show", :controller=>"superheroes", :team_id=>#<Team id: 1, name: "Watchmen", publisher: "DC", created_at: "2016-10-22 04:04:46", updated_at: "2016-10-22 04:04:46">} missing required keys: [:id]
I must just be using the form_for incorrectly. I can create superheroes in the console via: watchmen.superheroes.create(name:"The Comedian",true_identity:"Edward Blake") and when the page is generated my @superhero is a blank instance of that class.
Any help?
EDIT: It turned out to be an irregular plural situation. I updated the code below to show what worked overall.
My routes: routes.rb
Rails.application.routes.draw do
root to: 'teams#index'
resources :teams do
resources :superheroes
end
end
In '/app/views/superheroes/new.html.erb'
<%= form_for [@team,@superhero] do |f| %>
<p>Name</p>
<p><%= f.text_field :name %></p>
<p>True Identity</p>
<p><%= f.text_field :true_identity %></p>
<p><%= f.submit 'SAVE' %></p>
<% end %>
In superheroes_controller.rb
def new
@superhero = @team.superheroes.build
end
Turns out what I needed to do was create a migration to rename :superheros to :superheroes
class RenameTable < ActiveRecord::Migration[5.0]
def change
rename_table :superheros, :superheroes
end
end
And then add to inflections.rb:
ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.irregular 'superhero', 'superheroes'
end
That was doozy.