2016-06-01 2 views
0

사용자가 contest_questions 몇 가지를 예측하는 항목에 대한 양식을 작성하려고합니다.3 차 모델을 기반으로 중첩 된 폼 질문 구성

즉, 필자는 tipster-contest와 관련된 contest_questions를 동적으로 가져 와서 사용자가 해당 질문 각각에 대한 예측으로 항목을 등록하게하려는 것입니다.

어떻게하면됩니까? 지금부터 나는 분야는 contest_question 블록 내에서 실행되지 않습니다 <%= f.fields_for :predictions do |prediction| %> 때문에 게재되지 않습니다 내가 contest_question.fields_for ...로 변경하면 내가 얻을 #

tipster_contest에 대한 '

정의되지 않은 메서드`fields_for .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 %> 
,

그리고 내 schema.rb의 관련 부분은 해당이 필요할 것이다 경우 :

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 

답변

0

그것을 알아 내기 위해 관리하고 적어도이 작업을 진행. 나는 해결책이 레일 표준의 관점에서 좋은 것인지 모른다. 어쨌든 여기있다 :

_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 
관련 문제