Reputation: 319
I'm getting the following error when posting a form: Couldn't find Team without an ID
I have the below post parameters
{"utf8"=>"✓",
"_method"=>"put",
"authenticity_token"=>"knq4dG1U/5NJxMD6KYxfOpKd3CuOBHRlp6xCwdpwCnQ=",
"match"=>{"name"=>"latest match",
"date(1i)"=>"2013",
"date(2i)"=>"5",
"date(3i)"=>"19",
"teams_attributes"=>{"1368967240149"=>{"name"=>"Navi",
"id"=>"1"}}},
"commit"=>"Update Match",
"match_id"=>"2"}
Model:
team has_many :matchips
team has_many :matches :through => matchips
match has_many :matchips
match has_many :teams :through => matchips
Teams Controller:
def create
@team = Team.find(params[:team_id]) <-----fails here!
redirect_to @match
end
Form:
<%= nested_form_for @match, :url => {:action => "add_team_to_match_post"} do |f| %>
<% if @match.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@match.errors.count, "error") %> prohibited this match from being saved:</h2>
<ul>
<% @match.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :date %><br />
<%= f.date_select :date %>
</div>
<%= f.fields_for :teams, :html => { :class => 'form-vertical' } do |builder| %>
<%= builder.label "Team Name:" %>
<%= builder.autocomplete_field :name, autocomplete_team_name_teams_path, :update_elements => {:id => "##{form_tag_id(builder.object_name, :id)}" },:class => "input-small",:placeholder => "Search" %>
<%= builder.hidden_field :id %>
<% end %>
<%= f.link_to_add raw('<i class="icon-plus-sign"></i>'), :teams, :class => 'btn btn-small btn-primary' %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
So i basically have a many-to-many relationship between matches and teams. using nested_form for the matches, but the issue is that it's looking for the association before creating or updating, i want it. I previously done this with a many to one association where the child model would get created when the parent gets created or updated, on this occasion i already have the teams all i'm doing is passing the id and name via the post/put request so i can associate it to that match.
If there is a better way to associate already created entities then please let me know.
Upvotes: 4
Views: 1024
Reputation: 14408
has_many
for Matches <> Teams is an overkill. Please see this solution for mocking a has_two relationship. That would simplify your forms and URLs quite a lot.
Upvotes: 0
Reputation: 10684
After looking at this and asuming in team_attributes the key id is the id of team.
"match"=>{"name"=>"latest match",
"date(1i)"=>"2013",
"date(2i)"=>"5",
"date(3i)"=>"19",
"teams_attributes"=>{"1368967240149"=>{"name"=>"Navi",
"id"=>"1"}}}
Do this in controller
team_key = params['match']['teams_attributes'].keys.first
team_id = params['match']['teams_attributes']['team_key']['id']
Team.find(team_id)
OR
Another choice is available to do same thing
If you select team by autocomplete then after selecting team by ajax you can also add hidden field with name team_id and it value will be selected team id.
then you can easily access params[:team_id]
Let me suggest you new way of thinking
what if, if you think a match belongs to many teams remove middle table
and on match new and edit form select two teams whose match you want to held.
for reference look at this http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html
why I'm asking you do this? The answer is you have to create a match between already existing teams and no need to save match on team save.
But on match save you have to save team.
Hope this cure
Upvotes: 2
Reputation: 2967
You probably need something like:
def add_team_to_match_post
@match = Match.find(params[:match_id])
params[:teams_attributes].each_value do |team_attributes|
team = Team.find(team_attributes[:id])
@match.teams << team
team.matches << @match
end
redirect_to @match
end
Basically, this is iterating through every team in the teams_attributes
hash and adding it to the match object (since this is a many-to-many)
Upvotes: 2