1

ユーザーのプロファイルには1つのアドレスが割り当てられていますが、ユーザーは仮想「アドレス帳」に多くのアドレスを持つことができる一連のモデルを作成しようとしています. ユーザーは、自分のすべてのアドレスからデフォルトのアドレスを取得し、それをプロファイルに home_address として割り当てることができるはずです。

アドレスにはさまざまな種類があります。自宅の住所もありますが、追加のフィールドを持つ会社や銀行の住所もあります。そのため、ポリモーフィズムを使用する必要があります。

モデルを作成しました:

class Addresser < ActiveRecord::Base

  belongs_to :addressable,  :polymorphic => true
  belongs_to :address,      :polymorphic => true

  attr_accessible :address_id, :address_type

end

class HomeAddress < ActiveRecord::Base

  has_one :addresser, :as => :address, :inverse_of => :address

  attr_accessible :name, :city, :zip, :street, :state, :country

end

class Profile < ActiveRecord::Base

  has_one     :home_address,  :through => :addresser,
                              :source => :address, :source_type => 'HomeAddress', 
                              :autosave => true

  has_one     :addresser,     :as => :addressable, :inverse_of => :addressable, 
                              :autosave => true

  attr_accessible :name, :gender

end

すべてがほぼ正常に機能していますが、モデルを保存した後、Rails はフィールドの 1 つを更新していません。

profile_data = {
    :name    => 'Some User',
    :gender => 'm'
}

address_data = {
   :street => 'Streeting 7',
   :country => 'PL',
   :city => 'New Rails',
 }

my_profile = Profile.new(profile_data)

=> #<Profile id: nil, name: "Some User", gender: "m", created_at: nil, updated_at: nil>

my_address = HomeAddress.new(address_data)

=> #<HomeAddress id: nil, street: "Streeting 7", city: "New Rails", country: "PL

my_profile.home_address = my_address

INSERT INTO `addressers` (`address_id`, `address_type`, `addressable_id`, `addressable_type`)
VALUES (NULL, 'HomeAddress', NULL, 'Profile')
COMMIT

=> #<HomeAddress id: nil, name: "Sir Adam Rails", street: "Streeting 7", city: "New Rails", country: "PL">

my_profile.save!

 INSERT INTO `profiles` (`created_at`, `name`, `gender`, `updated_at`)
 VALUES ('2012-06-23 10:07:51', 'Some User', 'm', '2012-06-23 10:07:51')

 INSERT INTO `home_addresses` (`city`, `country`,`street`)
 VALUES ('New Rails', 'PL', 'Streeting 7')

 UPDATE `addressers` SET `addressable_id` = 1 WHERE `addressers`.`id` = 1

 COMMIT
=> true 

上記では、addressable_id は更新されますが、address_id は更新されません。これにより、データベース セッションを再度開いた後、制約が無効になり、使用できなくなります。

Addresser.first

SELECT `addressers`.* FROM `addressers` LIMIT 1
=> #<Addresser id: 1, address_id: nil, address_type: "HomeAddress", addressable_id: 1, addressable_type: "Profile"> 

address_id が nil であるため、profile.home_address が見つかりません。

addressable の address_id を手動で更新せずにこれを修正できますか?

私のアプリのアーキテクチャでは、いくつかの初期設定でオブジェクト全体を構築し、アトミック セーブを実行する必要があるため、(プロファイルを所有する) ユーザーが作成される前にアドレスを構築して保存することは、弱いオプションです。

4

0 に答える 0