

# テーブル構成

## Area

| id | name |

## prefectures

| id | area_id | name |

## prefecture_areas

| id | prefecture_id | name |

## spots

| id | prefecture_id | prefecture_area_id | name |

buildを用いて、以下のようにデータを格納したいです。

## areas(地方を管理するテーブル)

[code]

    | id | name | 
    | -- | ---- |
    | 1  | 近畿 | 
    | 2  | 九州 |  
    
[/code]

## prefectures(県を管理するテーブル)

[code]

    | id | area_id | name | 
    | -- | ------- | ---- |
    | 1  | 1       | 兵庫 |
    | 2  | 2       | 沖縄 |
    
[/code]

## prefecture_areas(県をさらに細分化する必要がある県のみ、県内のエリアを管理するテーブル)

[code]

    | id | prefecture_id | name | 
    | -- | ------------- | ---- |
    | 1  | 1             | 南部 |
    
[/code]

## spots(観光地を管理するテーブル)

[code]

    | id | prefecture_id | prefecture_area_id | name   | 
    | -- | ------------- | ------------------ | ------ |
    | 1  | 1             | 1                  | 姫路城   
    | 1  | 2             | NULL               | 美ら海水族館
    
[/code]

兵庫県は、prefecture_areasを作り、spotsを登録  
沖縄県は、prefecture_areasを作らずに、spotsを登録

Modelの定義

[code]

        class Area < ActiveRecord::Base
          has_many :prefectures
        end
    
        class Prefecture < ActiveRecord::Base
          has_many :prefecture_areas
          has_many :spots
    
          belongs_to :area
        end
    
        class PrefectureArea < ActiveRecord::Base
          has_many :spots
    
          belongs_to :prefecture
        end
    
        class Spot < ActiveRecord::Base
          belongs_to :prefecture
          belongs_to :prefecture_area
        end
    
[/code]

このModelの定義で、Area から Spot まで同時にbuildし、  
spotsに姫路城を入れる際に、以下のようなコードを書きました。  
(formは用いずに、保存します。)

[code]

    Area.new(name: '近畿').prefectures.build(name: '兵庫').prefecture_areas.build(name: '南部').spots.build(name: '姫路城').save
    
[/code]

すると、

[code]

    INSERT INTO `spots` (`name`, `prefecture_area_id`, `created_at`, `updated_at`) VALUES ('姫路城', 1, '2016-10-23 09:36:13', '2016-10-23 09:36:13')
    
[/code]

となり、prefecture_idをspotsに入れてくれません。  
buildの段階で、spotsに、prefecture_idとprefecture_area_idを同時に入れることは不可能でしょうか？

長くなってしまいましたが、何卒よろしくお願いいたします。


CC BY-SA 4.0
2016-10-23T15:42:24.233
29847
2018-07-08T09:32:19.983
2018-07-08T09:32:19.983
754
19286
question
ruby-on-rails rails-activerecord
新規登録時にbuild(ActiveRecord)を用いて、親と関連付ける外部キーを2つセットする方法について


難しそうに思えます。  
prefecture_areas.build(name: '南部') は PrefectureArea のインスタンスを返します。
PrefectureAreaのインスタンスに対する.spots.buildで、Prefectureに対する.spots.buildではないので。  
二度に分けるか、全てのPrefectureがPrefectureAreaを持つようにしてSpotのbelongs_to
:prefectureを無くすかでは駄目でしょうか


CC BY-SA 3.0
2016-11-24T02:42:34.097
30632
2016-11-24T02:42:34.097
19645
29847
answer


試してないですけどコールバックで`prefecture`を設定してやればいいような気がします。

[code]

    class Spot < ActiveRecord::Base
      belongs_to :prefecture
      belongs_to :prefecture_area
    
      before_validation(on: :create) do
        self.prefecture = self.prefecture_area.prefecture if self.prefecture_area
        true #nilよけ
      end
    end
    
[/code]


CC BY-SA 3.0
2017-04-20T05:10:40.363
34144
2017-04-20T05:10:40.363
5793
29847
answer