Learn how to use build (ActiveRecord) to set two foreign keys associated with the parent during new registration.

Asked 2 years ago, Updated 2 years ago, 84 views

| id | name |

| id | area_id | name |

| id | perfect_id | name |

| id | perfect_id | perfect_area_id | name |

I would like to store the data using build as follows.

 | id | name | 
| -- | ---- |
| 1 | Kinki | 
| 2 | Kyushu |  
 | id | area_id | name | 
| -- | ------- | ---- |
| 1 | 1 | Hyogo |
| 2 | 2 | Okinawa |
 | id | perfect_id | name | 
| -- | ------------- | ---- |
| 1 | 1 | South |
 | id | perfect_id | perfect_area_id | name | 
| -- | ------------- | ------------------ | ------ |
| 1 | 1 | 1 | Himeji Castle   
| 1|2|NULL|Beautiful Sea Aquarium

Hyogo prefecture created a perfect_areas and registered spots
Okinawa prefecture registers spots without creating a perfect_areas

Define Model

class Area<ActiveRecord::Base
      has_many —prefectures
    end

    class Prefecture <ActiveRecord::Base
      has_many —prefect_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 —prefect_area
    end

By definition of this model, build from Area to Spot at the same time and
When I put Himeji Castle in the spots, I wrote the following code.
(Do not use the form, save it.)

Area.new(name: 'Kinki') .prefectures.build(name: 'Hyogo') .prefecture_areas.build(name: 'Southern') .spots.build(name: 'Himeji Castle').save

Then,

INSERT INTO `spots`(`name`, `prefecture_area_id`, `created_at`, `updated_at`) VALUES('Himeji Castle', 1,'2016-10-2309:36:13', '2016-10-2309:36:13')

Therefore, they will not put the perfect_id into the spots.
Is it impossible to put the perfect_id and the perfect_area_id in the spots at the same time at the build stage?

It's been a long time, but I appreciate your cooperation.

ruby-on-rails rails-activerecord

2022-09-30 14:32

2 Answers

I haven't tried it, but I think I should set prefecture on the callback.

class Spot <ActiveRecord::Base
  belongs_to —prefecture
  belongs_to —prefect_area

  before_validation(on::create)do
    self.prefecture=self.prefecture_area.prefecture if self.prefecture_area
    true#nil protection
  end
end


2022-09-30 14:32

It seems difficult.
perfect_areas.build(name: 'southern') returns an instance of PrefectureArea because it is .spots.build for the instance of PrefectureArea and not .spots.build for Prefecture.
Would it be possible to divide it into two or eliminate the belts_to:prefecture of Spot by ensuring that all Prefectures have a PrefectureArea?


2022-09-30 14:32

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.