0

私は競合リーダーボードのためのレールアプリを構築しています。データモデルは複数のネストされたフォームを1つの送信ボタンで提出する

class Tournament 
    has_many :events 
end 

class User 
    has_many :entries 
    has_many :events, through: :entries 
end 

class Events 
    has_many :entries 
    belongs_to :tournament 
end 

class Entry 
    belongs_to :user 
    belongs_to :event 
end 

各トーナメント2つのイベントを有しており、ユーザがイベントあたり4つのエントリまで入力することができるので、トーナメントあたり8つのエントリの合計です。私は1つのフォームに1つの送信ボタンで8つのエントリーをすべて入力できるようにしたいと思います。

マイルート

resources :entries, except: [:index, :show] do 
    collection do 
    match 'create_collection', via: [:create] 
    end 
end 

私はこれまで、まだそれを持っていないのに、私はまた、エントリを処理するために、エントリのコントローラでCREATE_COLLECTIONメソッドを持っています。私はフォームが正しく動作するようにする方法がわかりません。ビュー/トーナメント/ index.html.hamlによってレンダリング部分であり、トーナメント2つのイベント・インスタンスであるnext_eventsを通過

_form.html.haml(

.entry-form 
    = form_tag create_collection_entries_path do |form| 
    - next_events.each do |event| 
     = event.name 
     = fields_for "events[]", event do |f| 
     - 4.times do 
      = f.fields_for :entries do |f| 
      = f.label_tag 'player' 
      = f.text_field 'player' 

    = submit_tag "Submit", class: "btn btn-success" 

Iなどのフォームが表示され期待していたが、私は、送信ボタンをクリックしたときにのみ、最後の4つのエントリはのparamsに提出され、イベントIDが、私は両方のイベントのために、すべてのエントリのパラメータが正しいで提出することを得るにはどうすればよい

"events"=>[{"entries_attributes"=> 
    {"0"=>{"player"=>"player5","id"=>"33"}, 
    "1"=>{"player"=>"player6", "id"=>"34"}, 
    "2"=>{"player"=>"player7", "id"=>"35"}, 
    "3"=>{"player"=>"player8", "id"=>"36"}}}], 
"commit"=>"Submit"} 

を渡されていませんイベントID?

答えて

1

私の研究は、レールは1つのフォームで1つのフォームで複数のモデルインスタンスをサブミットする方法を提供していないことを示しています。私はthisthisを見ましたが、それは私のためにはうまくいきませんでした。だから私は自分自身を転がした。

paramsハッシュのすべての値をかなり管理しやすい形で送信するためのフォーム。最も洗練されたソリューションではなく、バックエンドでかなりの処理が必要です。しかし、私はこれをもっと難解な方法で行う方法を見つけることができません。

.entry-form.on 
    = form_tag create_collection_entries_path(@user.id) do 
    - Tournament.next.events.each do |event| 
     %div= event.name 
     %div 
     - @num_of_entry_forms.times do |n| 
      %div 
      = label_tag 'player' 
      = text_field_tag "event[#{event.id}][entries][player_#{n}]" 

    = submit_tag "Submit", class: "btn btn-success" 

routes.rbを

resources :entries, except: [:index, :show] do 
    collection do 
    get '/new_collection/:user_id', to: 'entries#new_collection', as: 'new_collection' 
    post '/create_collection/:user_id', to: 'entries#create_collection', as: 'create_collection' 
    end 
end 

entries_controller.rb

def new_collection 
    @num_of_entry_forms = EventEntryCollectionCreator::MAX_ENTRIES_PER_EVENT 
    @user = User.find(params[:user_id]) 
end 

def create_collection 
    @eec = EventEntryCollection.new(params) 
    if @eec.save 
    redirect_to root_path 
    else 
    render :new_collection 
    end 
end 

form.html.haml

私はまだ、サービスモデルであるEventEntryCollectionCreatorに取り組んでいますしかしここにはその核心があります。

MAX_ENTRIES_PER_EVENT = 4 

def save 
    params["event"].each do |event| 
    event.last["entries"]["player"].each do |entry| 
     entry = Entry.new(event_id: event.first, user_id: user_id, player: entry.last) 
     @entries_collection << entry 
    end 
    end 
    save_collection 
end 

private 
def save_collection 
    @entries_collection.each do |entry| 
    if valid_entry? 
     entry.save 
     @valid_models << entry 
    else 
     @invalid_models << entry 
    end 
    end 
end 

これは最も洗練された解決策ではありませんが、問題を解決すると述べています。良い点は、乱雑なバックエンド処理がコントローラからそのサービスモデルに抽象化されていることです。否定的な側面には、いくつかのコードの匂いがあり、ハッシュ構造のことをあまり知っていなければならないハッシュやオブジェクトへの値がたくさんあります。

私は他の解決策や改善がこの作業の進行中です。

関連する問題