Nested forms

Mam problem z formularzem dla new:

= form_for(@match) do |f|
  = f.label :match_date
  = f.date_select :match_date, :order => [:day, :month, :year]
  = f.label :player_ids, 'Select players'
  = f.collection_select :player_ids, @players, :id, :lastname, {}, { multiple: true }

  = f.fields_for :match_edits do |ff|
    = ff.label :result
    = ff.number_field :result, in: 0..10
  %div
    = f.button :submit

Kiedy wybieram dwóch graczy chcę dla każdego z nich podać wynik meczu mniej więcej tak:

id: 1, match_id: 1, player_id: 1, result: 4

id: 2, match_id: 1, player_id: 2, result: 10

Tak wygląda new w MatchController:

  def new
    @match = Match.new
    @players = Player.all
    2.times {@match.match_edits.build}
  end
...
  private

  def match_params
    params[:match].permit :match_date, player_ids: [], :match_edits_attributes => [:id, :result]
  end

Oraz model Match

class Match < ActiveRecord::Base

    has_many :match_edits
    has_many :players, through: :match_edits
    accepts_nested_attributes_for :match_edits, allow_destroy: true, reject_if: proc { |attrs| attrs['result'].blank? }

end

Model MatchEdit

class MatchEdit < ActiveRecord::Base

    belongs_to :match
    belongs_to :player

end

Kiedy wypełniam formularz i go zapisuje w tabeli MatchEdit zamiast dwóch rekordów dodaje mi cztery:

 #<ActiveRecord::Relation 
[#<MatchEdit id: 1, match_id: 1, player_id: 1, created_at: 
"2015-07-05 17:00:24", updated_at: "2015-07-05 17:00:24", result: 
nil>, #<MatchEdit id: 2, match_id: 1, player_id: 2, created_at: 
"2015-07-05 17:00:24", updated_at: "2015-07-05 17:00:24", result: 
nil>, #<MatchEdit id: 3, match_id: 1, player_id: nil, created_at: 
"2015-07-05 17:00:24", updated_at: "2015-07-05 17:00:24", result: 
10>, #<MatchEdit id: 4, match_id: 1, player_id: nil, created_at: 
"2015-07-05 17:00:24", updated_at: "2015-07-05 17:00:24", result: 6>]

Może mi ktoś wyjaśnić co zrobiłem źle?

Dwa pierwsze rekordy są utworzone przez pole player_ids (z automatu buduje pośredników czyli match_edit) a kolejne dwa przez fields_for :match_edits.

Spróbuj w ten sposób:

= form_for(@match) do |f|
  = f.label :match_date
  = f.date_select :match_date, :order => [:day, :month, :year]

  = f.fields_for :match_edits do |ff|
    = f.label :player_id, 'Select player'
    = f.collection_select :player_id, @players, :id, :lastname, {}, { multiple: false }
    = ff.label :result
    = ff.number_field :result, in: 0..10
  %div
    = f.button :submit

I w kontrolerze

 def match_params
    params[:match].permit :match_date, :match_edits_attributes => [:id, :result, :player_id]
  end

Dzięki działa. Tylko jeszcze musiałem zmienić

= f.label :player_id, 'Select player'
= f.collection_select :player_id, @players, :id, :lastname, {}, { multiple: false }

na

= ff.label :player_id, 'Select player'
= ff.collection_select :player_id, @players, :id, :lastname, {}, { multiple: false }

ach… tak tak :wink: oczywiście - moje niedopatrzenie :blush: