2016-06-01 6 views
0

Ich möchte ein Formular für Einträge erstellen, in dem ein paar contest_questions vom Benutzer vorhergesagt werden.Verschachtelte Formularfragen basierend auf einem dritten Modell erstellen

Das bedeutet, ich möchte dynamisch die contest_questions im Zusammenhang mit dem Tippgeber-Wettbewerb abrufen und dann den Benutzer einen Eintrag mit Vorhersagen für jede dieser Fragen registrieren lassen.

Wie kann ich das tun? Ab jetzt habe ich die Felder zeigen sich nicht, da <%= f.fields_for :predictions do |prediction| %> nicht innerhalb des contest_question Block ausführt und wenn ich es contest_question.fields_for ... ändern bekomme ich ein

nicht definierte Methode `fields_for‘ für #

tipster_contest .rb

class TipsterContest < ActiveRecord::Base 
    belongs_to :bookmaker 
    belongs_to :game 
    has_many :entries 
    has_many :contest_questions 

    extend FriendlyId 
    friendly_id :name, use: [:slugged, :history] 

    enum status: { "Scheduled" => 0, "Open" => 1, "Closed" => 2, "Graded" => 3 } 

    scope :published?, -> { where(published: :true) } 
end 

entry.rb

class Entry < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :tipster_contest 
    has_many :predictions 

    accepts_nested_attributes_for :predictions 
end 

contest_question.rb

class ContestQuestion < ActiveRecord::Base 
    belongs_to :tipster_contest 
    has_many :predictions 
end 

prediction.rb

class Prediction < ActiveRecord::Base 
    belongs_to :entry 
    has_one :contest_question 
end 

_form.html.erb

<%= form_for(@entry) do |f| %> 
    <% @contest.contest_questions.order(name: :asc).each do |contest_question| %> 
    <%= f.fields_for :predictions do |prediction| %> 
     <div class="field"> 
     <%= prediction.label contest_question.name %> 
     <%= prediction.select(:prediction, @contest.teams) %> 
     </div> 
     <div class="field"> 
     <%= prediction.label :wager_amount %> 
     <%= prediction.input :wager_amount %> 
     </div> 
    <% end %> 
    <% end %> 

    <div class="actions"> 
    <%= f.submit "Save entry", :class => "btn btn-success" %> <%= link_to 'Back', bets_path, :class => "btn btn-danger" %> 
    </div> 
<% end %> 

und der relevante Teil meiner schema.rb wenn das erforderlich wäre:

create_table "contest_questions", force: true do |t| 
    t.integer "tipster_contest_id" 
    t.string "name" 
    t.string "result" 
    t.integer "min_wager" 
    t.integer "max_wager" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

    create_table "entries", force: true do |t| 
    t.integer "user_id" 
    t.integer "tipster_contest_id" 
    t.integer "bankroll" 
    t.integer "won" 
    t.string "currency" 
    t.boolean "entry_valid" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

    create_table "predictions", force: true do |t| 
    t.integer "entry_id" 
    t.integer "contest_question_id" 
    t.string "prediction" 
    t.integer "wager_amount" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

    create_table "tipster_contests", force: true do |t| 
    t.integer "bookmaker_id" 
    t.integer "game_id" 
    t.string "name" 
    t.string "tournament" 
    t.integer "status",    default: 0 
    t.text  "rules" 
    t.integer "prizepool" 
    t.string "currency" 
    t.text  "payout_structure" 
    t.integer "tipster_wallet" 
    t.string "teams",    default: [], array: true 
    t.datetime "registration_open" 
    t.datetime "registration_close" 
    t.boolean "published",   default: false 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    t.string "logo" 
    t.text  "description" 
    t.string "slug" 
    end 

    add_index "tipster_contests", ["slug"], name: "index_tipster_contests_on_slug", using: :btree 

Antwort

0

Managed es herauszufinden und zumindest bekommen sie arbeiten. Ich weiß nicht, ob die Lösung in Bezug auf den Schienenstandard gut ist. Auf jeden Fall ist es hier:

_form.html.erb

<% title("#{@contest.name}") %> 
<% description("Join #{@contest.name} and use your eSports knowledge to win extra cash or in-game skins for games like CS:GO, Dota 2, etc.") %> 

<p id="notice"><%= notice %></p> 

<%= form_for(@entry) do |f| %> 
    <% if @entry.errors.any? %> 
    <div id="error_explanation"> 
     <h2><%= pluralize(@entry.errors.count, "error") %> prohibited this entry from being saved:</h2> 

     <ul> 
     <% @entry.errors.full_messages.each do |message| %> 
      <li><%= message %></li> 
     <% end %> 
     </ul> 
    </div> 
    <% end %> 

    <%= f.hidden_field 'tipster_contest_id', :value => @contest.id %> 

    <div class="t_container"> 
    <div class="t_row"> 
     <div class="t_left"><b>Placement</b></div> 
     <div class="t_middle"><b>Team</b></div> 
     <div class="t_right"><b>Wager Amount</b></div> 
    </div> 

    <%= f.fields_for :predictions, @predictions do |p| %> 
     <div class="t_row"> 
     <div class="t_left"><%= @entry.contest_questions.order(:name => :asc)[p.index].name %></div> 
     <div class="t_middle"><%= p.select :prediction, @contest.teams %></div> 
     <div class="t_right"><%= p.text_field :wager_amount, label: "Wager amount" %></div> 
     <%= p.hidden_field 'contest_question_id', :value => @entry.contest_questions.order(:name => :asc)[p.index].id %> 
     </div> 
    <% end %> 
    </div> 

    </br> 

    <div class="actions"> 
    <%= f.submit "Save entry", :class => "btn btn-success" %> <%= link_to 'Back', bets_path, :class => "btn btn-danger" %> 
    </div> 
<% end %> 

entries_controller.rb

class EntriesController < ApplicationController 
    before_action :set_entry, only: [:show, :edit, :update, :destroy] 

    # GET /entries 
    # GET /entries.json 
    def index 
    @entries_open = current_user.entries.includes(:tipster_contest).where(:tipster_contests => {status: 1}) 
    @entries_closed = current_user.entries.includes(:tipster_contest).where(:tipster_contests => {status: 2}) 
    @entries_graded = current_user.entries.includes(:tipster_contest).where(:tipster_contests => {status: 3}) 
    @contests = TipsterContest.where(status: 0..1).includes(:game) 
    end 

    # GET /entries/1 
    # GET /entries/1.json 
    def show 
    end 

    # GET /entries/new 
    def new 
    if user_signed_in? 
     begin 
     @contest = TipsterContest.friendly.find(params[:contest]) 
     redirect_to tipster_contests_path(@contest), notice: "#{@contest.name} does not accept entries at this point. Registration opens at: #{@contest.registration_open} and closes at: #{@contest.registration_close}." and return true unless @contest.status == "Open" 
     @entry = Entry.new(tipster_contest: @contest) 
     @predictions = [] 
     @contest.contest_questions.order(name: :asc).each do |cq| 
      @predictions << Prediction.new(entry: @entry.id, contest_question_id: cq.id) 
     end 
     rescue 
     redirect_to tipster_contests_path, notice: 'Could not find a tipster-contest with that ID' 
     end 
    else 
     redirect_to new_user_registration_path, notice: 'You need to sign up to enter the tipster contest!' 
    end 
    end 

    # GET /entries/1/edit 
    def edit 
    if user_signed_in? 
     @contest = @entry.tipster_contest 
     @predictions = @entry.predictions 
     redirect_to tipster_contests_path, notice: 'This is not your entry to edit' and return true unless @entry.user == current_user 
    else 
     redirect_to new_user_registration_path, notice: 'You need to sign up to enter or edit a tipster contest entry!' 
    end 
    end 

    # POST /entries 
    # POST /entries.json 
    def create 
    @entry = Entry.new(entry_params) 

    @predictions = @entry.predictions 

    @contest = @entry.tipster_contest 
    @entry.user = current_user 
    @entry.won = 0 
    @entry.bankroll = @contest.tipster_wallet 
    @entry.currency = @contest.currency 

    respond_to do |format| 
     if @entry.save 
     format.html { redirect_to @entry, notice: 'Entry was successfully created.' } 
     format.json { render :show, status: :created, location: @entry } 
     else 
     format.html { render :new } 
     format.json { render json: @entry.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    # PATCH/PUT /entries/1 
    # PATCH/PUT /entries/1.json 
    def update 
    @contest = @entry.tipster_contest 
    #@predictions = @entry.predictions 

    respond_to do |format| 
     if @entry.update(entry_params) 
     format.html { redirect_to @entry, notice: 'Entry was successfully updated.' } 
     format.json { render :show, status: :ok, location: @entry } 
     else 
     format.html { render :edit } 
     format.json { render json: @entry.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    # DELETE /entries/1 
    # DELETE /entries/1.json 
    def destroy 
    @entry.destroy 
    respond_to do |format| 
     format.html { redirect_to entries_url, notice: 'Entry was successfully destroyed.' } 
     format.json { head :no_content } 
    end 
    end 

    private 
    # Use callbacks to share common setup or constraints between actions. 
    def set_entry 
     @entry = Entry.find(params[:id]) 
    end 

    # Never trust parameters from the scary internet, only allow the white list through. 
    def entry_params 
     params[:entry].permit(:id, :tipster_contest_id, predictions_attributes: [:prediction, :wager_amount, :contest_question_id, :id]) 
    end 
end 
Verwandte Themen