2016-11-08 5 views
0

編集:主な問題は、参照フィールドを追加したときに、フィールドが外部キーとしてマークされていないように、劇場:参照と劇場:参照をしなかったことでした。これらの移行を元に戻して正しく再割り当てすると、私はこの作業を行うことができました。手動で参照オブジェクトをRailsに保存する方法

私のショータイムコントローラーでは、ユーザーが入力した劇場のシアターIDをシアターIDに自動的に設定しようとしていますが、整数またはストリングとして保存しようとするとエラーが発生します。それでも、劇場のオブジェクトとして保存しようとすると、コンソールから「Unpermittedパラメータ:劇場」、レールアプリケーションから「劇場が存在する」というエラーが表示されます。

showtimes_controller:

class ShowtimesController < ApplicationController 
    before_action :set_theater, only: [:create, :edit] 
    before_action :set_showtime, only: [:show, :edit, :update, :destroy] 

    # GET /showtimes 
    # GET /showtimes.json 
    def index 
    @showtimes = Showtime.all 
    end 

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

    # GET /showtimes/new 
    def new 
    @showtime = Showtime.new 
    end 

    # GET /showtimes/1/edit 
    def edit 
    end 

    # POST /showtimes 
    # POST /showtimes.json 
    def create 

    @showtime = Showtime.new(showtime_params) 

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

    # PATCH/PUT /showtimes/1 
    # PATCH/PUT /showtimes/1.json 
    def update 
    respond_to do |format| 
     if @showtime.update(showtime_params) 
     format.html { redirect_to @showtime, notice: 'Showtime was successfully updated.' } 
     format.json { render :show, status: :ok, location: @showtime } 
     else 
     format.html { render :edit } 
     format.json { render json: @showtime.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    # DELETE /showtimes/1 
    # DELETE /showtimes/1.json 
    def destroy 
    @showtime.destroy 
    respond_to do |format| 
     format.html { redirect_to showtimes_url, notice: 'Showtime was successfully destroyed.' } 
     format.json { head :no_content } 
    end 
    end 

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

    def set_theater 
     screenInfo = Screen.where("id = ?", params[:showtime][:screen]) 
     params['showtime']['theater'] = Theater.find(screenInfo[0]['theater_id']) 
    end 

    # Never trust parameters from the scary internet, only allow the white list through. 
    def showtime_params 
     params.require(:showtime).permit(:date, :time, :archived, :movie_id, :theater, :screen) 
    end 
end 

上映モデル:

class Showtime < ApplicationRecord 
    belongs_to :movie 
    belongs_to :theater 
end 

上映時間_form

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

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

    <div class="field"> 
    <%= f.label :date %> 
    <%= f.date_select :date %> 
    </div> 

    <div class="field"> 
    <%= f.label :time %> 
    <%= f.time_select :time %> 
    </div> 

    <div class="field"> 
    <%= f.label :archived %> 
    <%= f.check_box :archived %> 
    </div> 

    <div class="field"> 
    <%= f.label :movie_id %> 
    <%= f.text_field :movie_id %> 
    </div> 

    <div class="field"> 
    <%= f.label :screen %> 
    <%= f.text_field :screen %> 
    </div> 

    <%= f.hidden_field :theater, :value => "" %> 

    <div class="actions"> 
    <%= f.submit %> 
    </div> 
<% end %> 

エラー整数として保存しよう:

Theater(#70015922237640) expected, got Fixnum(#11723820) 
文字列として保存しようとする

エラー:劇場オブジェクトとして保存しようと

Theater(#70015868755420) expected, got String(#11739240) 

ログは:

Started POST "/showtimes" for IP at 2016-11-08 20:22:37 +0000 
Processing by ShowtimesController#create as HTML 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"nENPV5d6YRXdcx3H+Xa9ZypGtyFlaTg+zyENGB10TmW9OyWxLR9Dsl7nDoG9irq+3qApiNA2/oEqL5RZ0SXorA==", "showtime"=>{"date(1i)"=>"2016", "date(2i)"=>"11", "date(3i)"=>"8", "time(1i)"=>"2016", "time(2i)"=>"11", "time(3i)"=>"8", "time(4i)"=>"20", "time(5i)"=>"22", "archived"=>"0", "movie_id"=>"2", "screen"=>"1", "theater"=>""}, "commit"=>"Create Showtime"} 
    [1m[36mScreen Load (0.3ms)[0m [1m[34mSELECT "screens".* FROM "screens" WHERE (id = '1')[0m 
    [1m[36mTheater Load (0.2ms)[0m [1m[34mSELECT "theaters".* FROM "theaters" WHERE "theaters"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]] 
Unpermitted parameter: theater 
    [1m[35m (0.1ms)[0m [1m[36mbegin transaction[0m 
    [1m[36mMovie Load (0.2ms)[0m [1m[34mSELECT "movies".* FROM "movies" WHERE "movies"."id" = ? LIMIT ?[0m [["id", 2], ["LIMIT", 1]] 
    [1m[35m (0.2ms)[0m [1m[31mrollback transaction[0m 
    Rendering showtimes/new.html.erb within layouts/application 
    Rendered showtimes/_form.html.erb (13.6ms) 
    Rendered showtimes/new.html.erb within layouts/application (16.4ms) 
Completed 200 OK in 323ms (Views: 86.5ms | ActiveRecord: 3.9ms) 

がどのように地獄私は、このパラメータを保存しますか?

+1

あなたの代わりにtheater_idの劇場を持っているのはなぜ? – inye

+0

'許可されていないパラメータ:劇場'これは注意して考慮する重要なことです...あなたの 'permit/require'行に何かがないことを意味します –

答えて

0

オブジェクトをインスタンス変数に代入して保存する前にそれを割り当ててみましたか?あなたの作成したアクションにあなたのbefore_action

def set_theater 
    @theather = ... # Code to find the theather 
end 

def create 
    @showtime = Showtime.new(showtime_params) 
    @showtime.theather = @theather 
    ... # Code to save and handle errors 
end 
+0

' ActiveModel :: MissingAttributeError不明な属性 'theater_id'):'これを使っているエラーです。なぜ私はオブジェクト全体を提供しているのかわからない – vman411gamer

+0

byebugのようなデバッグ用の宝石を使っていますか? 'set_theather'メソッドが適切に動作しているかどうかを知ることは賢明です。 – rebagliatte

+1

"ActiveModel :: MissingAttributeError"これは面白いことです...このエラーのコンテキストをもっとわかりやすく教えてください。あなたのコンソールウィンドウまたはログファイル(log/development.log)を見て、そのエラーを見つけてください。スタックトレースがあるはずです(ファイル名の後ろに30文字程度の行が続きます)。それをコピーして元の質問に貼り付けます。このスタックトレースは、このエラーの原因となったコードのラインを正確に示してくれます。これは正確に何が間違っていたのかを理解する上で本当に役立ちます。 –

0

は、あなたのコード内のいくつかの場所でtheater代わりのtheater_id使用し、そしてあなたはそれを変更する必要がありますこれが働くためには、すべての場所で。

私たちのフォームでは選択できません... htmlはtheaterのタイプを認識せず、1つ通過しないため、代わりにフォームをtheater_id(これは整数それは喜んで対処することができます)。

# eg here make sure it's a theater_id 
<%= f.hidden_field :theater_id, :value => @theater.id %> 

次 - あなたの必要/許可がいくつかのエラーを投げているものはおそらくです - あなたにもtheater_idさせることが必要になります。

def showtime_params 
    params.require(:showtime).permit(:date, :time, :archived, :movie_id, :theater_id, :screen) 
end 

今、あなたは、画面の情報を使用して、劇場をフェッチする必要があります

def set_theater 
    if params[:showtime].present? && params[:showtime][:screen_id].present? 
    screen_info = Screen.find(params[:showtime][:screen_id]) 
    @theater = Theater.find(screenInfo.theater_id) 
    end 
end 

注: - paramがなく、これはいくつかの回はnilとして通ってくるかもしれないことに注意してください(そうガード句は常に良いです)私は、レールの標準であることを命名・スキームを更新し、削除されましたthあなたは以下のようにのparamsに劇場を設定しようとするところINGの:

params['showtime']['theater'] = Theater.find(screenInfo[0]['theater_id']) 

私はあなたが実際にこのコード行で何をしようとしているのか分からないが、それが何であれ、のparamsことが動作しません。 paramsは "ユーザーから私たちに渡されて捨てられるものの集合"であると考えてください。私たちはそれを使って新しい値を作成し、コントローラーで作成します。それは、@variable sが

のためのものである何あなたがやろうとしているより多くの内容を説明することができますし、我々はそれを行うための正しい方法を考え出すだろう:)

+1

助けてくれてありがとうございました。劇場の代わりに参照:劇場を参照していたので、私はこのforeign_keyとしてマークされていませんでした。 – vman411gamer

関連する問題