2017-02-21 4 views
0

私は、has_many throughアソシエーションを持つActiveRecordモデルを持っています。イベントモデルには会場の列(文字列)があり、それを抽出して別のモデルにする必要があります。既存のレコードを削除せずに、has_manyの片面をActiveRecordモデルに置き換えるにはどうすればよいですか?

# Original Models 

class Event < ActiveRecord::Base 
    has_many :booking_events, dependent: :destroy 
    has_many :bookings, through: :booking_events 
end 

class Booking < ActiveRecord::Base 
    has_many :booking_events, dependent: destroy 
    has_many :events, through: :booking_events 
end  

class BookingEvent < ActiveRecord::Base 
    belongs_to :event 
    belongs_to :booking 
end 


# Refactored models 

class Event < ActiveRecord::Base 
    belongs_to :venue 
end 

class Venue < ActiveRecord::Base 
    has_many :events 

    has_many :booking_venues, dependent: :destroy 
    has_many :bookings, through: :booking_venues 
end 

class Booking < ActiveRecord::Base 
    has_many :booking_venues, dependent: destroy 
    has_many :venues, through: :booking_venues 
end  

class BookingVenue < ActiveRecord::Base 
    belongs_to :venue 
    belongs_to :booking 
end 

会場ではなく、イベントの関係を通じて、多くの今、多くの片側であるとして、私は会場のIDを追加して検索し、適切なvenue_idを関連付けるために、移行を使用していました。私は、列を削除したり、レコードがデータベースから削除されてnilにEVENT_IDを設定すると、それはもはやしかし、必要とされているように私には、イベントの関連付けを削除しないようにするために

class BookingVenue < ActiveRecord::Base 
    belongs_to :event # not needed, trying to remove 
    belongs_to :booking 
    belongs_to :venue 
end 

次のステップです。私はこれがdependent: destroyのためだと思います。

私はこれに正しく近づいていると思いますが、これがデータの移行や関連付けの更新の標準またはRailsの方法であるかどうかはわかりません。どんな勧告も高く評価されます。

答えて

0

アソシエーションテーブルを使用して新しいhas_manyを作成し、新しいモデルで動作するようにモデル定義を更新/名前を変更しました。

次の参照がキーだった:https://makandracards.com/makandra/15575-how-to-write-complex-migrations-in-rails

私は、元のモデルを照会するためのActiveRecordをサポートしているために、移行ファイルにモデルクラス定義を追加しました。従属値によるデータ操作の変更が制限されていないモデル定義については、依存関係を破棄から無効に変更するために、移行時に関連を一時的に無効にするRailsのオープンクラスの概念を使用しました。例えば

#migration file 

class CreateVenue < ActiveRecord::Migration 

    # temporarily override dependent assocation 
    class Event < ActiveRecord::Base 
    # has_many :booking_event, dependent: :destroy 
    has_many :booking_event, dependent: :nullify 
    end  

    # temporary model class definition for ActiveRecord support 
    class BookingEvent < ActiveRecord::Base 
    end 

    def change 
    # Used the previous model support to loop through and create 
    # the new association objects 

    # overriding the dependent: :destroy value above allows 
    # for deleting this table without deleting the other records 
    drop_table :booking_events 
    end 
end 
関連する問題