Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

Railsの自己結合②

はじめに
前回の続きです。Rails Developers MeetUpでお話聞きながら書いてます。

Railsで自己結合やってみる

前回、自己結合が何かイメージできたところで実装です。
親子関係のあるPersonクラスを元に考えていきます。

20181208054943_create_people.rb
class CreatePeople < ActiveRecord::Migration[5.1]
  def change
    create_table :people do |t|
      t.string :name
      t.references :person, foreign_key: true

      t.timestamps
    end
  end
end

Personモデルを作ります。
referencesで参照するカラムを作成し、外部キー制約も指定しています。

rails db:migrateします。

schema.rb
ActiveRecord::Schema.define(version: 20181208054943) do
  create_table "people", force: :cascade do |t|
    t.string "name"
    t.integer "person_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["person_id"], name: "index_people_on_person_id"
  end

Personテーブルが作成されました。referenceでは自動でperson_idを作成してくれます。indexも自動で貼ってくれます。
person_idを用いて親を参照できるようにします。

Person.rb
class Person < ApplicationRecord
  has_many :children, :class_name => 'Person', :foreign_key => 'person_id', dependent: :destroy
  belongs_to :parent, :class_name => 'Person', :foreign_key => 'person_id', optional: true
end

1対Nの関係になりますので、childrenを多数持つのでhas_many :children
その逆でparentは一人なので、belongs_to :parentとなります。
:class_nameはもちろんPersonですね。外部キーはperson_idを指定します。
dependantによって親が消えたら子も消えるようにしてます。

p = Person.create(name: "aaa")
p.children = [Person.create(name: "bbb")]
p
#=> #<ActiveRecord::Associations::CollectionProxy [#<Person id: 1, name: "aaa", person_id: 2, created_at: "2018-12-08 14:54:37", updated_at: "2018-12-08 14:54:37">]>

これで自己結合は完了です。実際に親を参照できるか試してみましょう。

p.children.first.parent
#=>#<Person id: 1, name: "aaa", person_id: nil, created_at: "2018-12-08 14:52:26", updated_at: "2018-12-08 14:52:26">

これで自己結合は完璧ですね!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
0
Help us understand the problem. What are the problem?