user901790
user901790

Reputation: 319

rails post params getting a id not found

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

Answers (4)

Subhas
Subhas

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

Taimoor Changaiz
Taimoor Changaiz

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

Adnan
Adnan

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

Reck
Reck

Reputation: 8772

change params[:team_id] to params[:teams_attributes][:id]

Upvotes: 0

Related Questions