0

私のアソシエーションをlocalhost:3000/controller_name/newに保存することができません。私はそれがbelongs_tofailing validationに起因すると信じていますが、私はそれを修正する方法がわかりません(ちょうどrequires:false/optional: trueを介してアソシエーションを削除することを超えて、その結果はわかりません)。私はこのtutorialの後に私の関係を作成しましたが、それは以前のバージョンのレール用でした。Rails 5で多態アソシエーショントランザクションが失敗する

イベント、企業、ユーザーなどに属している多相アドレステーブルがあります。イベントに追加しようとしています。

アドレスの移行 - あなたはそれがaddressableを参照して見ることができます:

class CreateAddresses < ActiveRecord::Migration[5.1] 
    def change 
    create_table :addresses do |t|  
     t.string :address 

     t.decimal :latitude, null: false, precision: 10, scale: 6, index: true 
     t.decimal :longitude, null: false, precision: 10, scale: 6, index: true 

     t.references :addressable, polymorphic: true, index: true 
    end 
    end 
end 

住所モデル:

class Address < ApplicationRecord 
    belongs_to :addressable, polymorphic: true 
end 

イベントモデル:

class Event < ApplicationRecord 
    has_one :address, as: :addressable 
    accepts_nested_attributes_for :address 
end 

・イベント・コントローラ:

class EventsController < ApplicationController 
    #...stuff... 

    # GET /events/new 
    def new 
    @event = Event.new 
    @event.address = @event.build_address 
    #@event.address = Address.new(addressable: @event) 
    #@event.address = @event.create_address 
    #@event.address = @addressable.User.new 
    end 

    #...stuff... 

私はイベントのアドレスを作成するために複数の方法を試してみました。ほとんどの場合、以下の項目が作成されました。addressableを使用するものは、Nilにクラッシュします。部分的

<%= simple_form_for @event do |f| %> 
    <%= f.input :name %> 
    <%= f.input :description %> 

    <%= f.simple_fields_for :address do |address| %> 
    <%= render :partial => 'shared/address/form', :locals => {:f => address} %> 
    <% end %> 

    <%= f.button :submit %> 
<% end %> 

アドレスの形式::

<!-- Google Maps Must be loaded --> 
<% content_for :head do %> 
    <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCMh8-5D3mJSXspmJrhSTtt0ToGiA-JLBc&libraries=places"></script> 
<% end %> 

<div id="map"></div> 

<%= f.input :address %> 
<%= f.input :latitude %> 
<%= f.input :longitude %> 

フォームを微レンダリング

#<Address id: nil, address: nil, latitude: nil, longitude: nil, addressable_type: "Event", addressable_id: nil> 

イベントフォーム(Simple_form宝石を使用します)。私が保存しようとすると、私は

Started POST "/events" for 127.0.0.1 at 2017-07-01 16:06:23 -0400 
Processing by EventsController#create as HTML 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"R0zlSs3UUNV3x8sQn5ocmE4jP12uOsFza7FezBAuhP4sw2MhF1OhixF8sAfDsLpfMEX7x5rhJ9HZfbKna8ncEA==", "event"=>{"name"=>"asd", "description" 
=>"asd", "address_attributes"=>{"address"=>"asd", "latitude"=>"1", "longitude"=>"1"}}, "commit"=>"Create Event"} 
    (0.1ms) begin transaction 
    (0.1ms) rollback transaction 

を取得し、私はnewページに保たれています。私はcreatebyebugを挿入し、@event.errorsを印刷した場合には示しています

#<ActiveModel::Errors:0x007fb29c34a9a8 @base=#<Event id: nil, name: "asd", description: "asd", min_users: nil, max_users: nil, start_time: nil, recurring: nil, created_at: nil, upd 
ated_at: nil>, @messages={:"address.addressable"=>["must exist"]}, @details={:"address.addressable"=>[{:error=>:blank}]}> 

にはどうすればaddress.addressableを作成することができますか?何かSOの答えが示唆しているように、必要性検証をオフにした結果はどうなりますか?

答えて

0

は、問題を発見し、深さでこれを議論blog postを書きました。本質的に私は2つの別々の問題に遭遇しました

1.私が受け取ったエラー - "address.addressable"=>["must exist"]。 address.addressableは、 '親'テーブルのタプルIDです。私の場合、それはイベントIDです。このエラーは、私たちがコントローラのcreate関数に保存しようとしたときに、この外部キーが新しいアドレスから見つからないことを伝えようとしています。私が質問したように、optional:trueにこの問題を無視するように設定すると、イベントを保存した後に何とか魔法のように埋められます。また、保存する前に、作成機能で手動で割り当てることもできます。

def create 
    @event = Event.new(event_params) 
    @event.address.addressable = @event #<<<<<<<<<<< manually assign address.addressable 
    respond_to do |format| 
    if @event.save #Saves the event. Addressable has something to reference now, but validation does not know this in time 
     format.html { redirect_to @event, notice: 'Event was successfully created.' } 
     format.json { render :show, status: :created, location: @event } 
    else 
     #dont forget to remove the 'byebug' that was here 
     format.html { render :new } 
     format.json { render json: @event.errors, status: :unprocessable_entity } 
    end 
    end 
end 

2.イベントIDは文字列でした。私のアドレスの移行では、addressable_idの整数型の別名であるt.references :addressable, polymorphic: true, index: trueを使用していました。文字列IDを使用するように移行を変更する必要があったため、references行を削除し、代わりにこの行を追加してください。

t.string :addressable_id, index: true 
t.string :addressable_type, index: true 

これは、ブログ記事で少し詳しく説明しています。

1

実行すくいデシベル:addressable_id、 * t.string:addressable_type および多くのためのスキーマ:* t.integer をたどるのようにダンプし、あなたが2つのフィールドを持っていることを確認し、デシベル/ schema.rb内のファイルを確認しますここでは詳細はActiverecord Polymorphic Associationsに関するリンクです、あなたのスキーマに問題がある場合は、その後、あなたは、マイグレーションを実行することができますイベントとして

t.references :addressable, polymorphic: true, index: true 

に従うポリモーフィックな関連を通じて多くのアドレスを持っているとして、あなたは住所 を作成するためにthis linkを使用して、以下にすることができますサンプルコード

あなたはevent.address @ @addressを使用していないこと
@address = @event.addresses.build(attributes = {}, ...) 

+0

私はまだそれをテストすることができませんでしたが、私はアドレスがアドレス指定可能な型を持っていることを知っています。元のテキストに '@ event.build_address'を使った出力を含めました。私は問題が、これがIdを空にしておくことだと思いますか? –

+0

@ event.addresses.build(レール提供のメソッド)を使用するときにhas_oneやhas_manyなどの接続をすでに設定している場合、IDを自動的に処理するため、手動で入力/入力する必要はありません – widjajayd

+0

私はイベントコントローラの 'new'関数で' @address = @ event.address.build'を試してみると、 ''未定義メソッド 'ビルド'をnil:NilClass'にしています。そして、#<イベント:0x007f3f288c0820>のための '未定義のメソッド 'アドレス'は意味しましたか? @ event.address.build'のアドレスアドレス= '。 '@ event.build_address'は動作しますが、フォームに渡されるときにこれらのプロパティを持ちます' {"id" => nil、 "address" => nil、 "latitude" => nil、 "longitude" => nil、 "addressable_type" = > "イベント"、 "addressable_id" => nil} 'なぜIDはそこにないのですか? –

関連する問題