前提
以下のような多対多のテーブルを有識者の方のアドバイスをもとに作成しました。
しかし、私の知識が浅く、コントローラの作り方が分からなくなってしまいました。
フレームワークは Rails 6 系、DBは PostgreSQL 13 系です。
モデルの状態
ruby
# app/models/song.rb class Song < ApplicationRecord has_many :composer_songs, dependent: :destroy has_many :composer_song_artists, through: :composer_songs has_many :lyricist_songs, dependent: :destroy has_many :lyricist_song_artists, through: :lyricist_songs has_many :arranger_songs, dependent: :destroy has_many :arranger_song_artists, through: :arranger_songs end # app/models/artist.rb class Artist < ApplicationRecord has_many :composer_songs, dependent: :destroy has_many :composer_song_songs, through: :composer_songs has_many :lyricist_songs, dependent: :destroy has_many :lyricist_song_songs, through: :lyricist_songs has_many :arranger_songs, dependent: :destroy has_many :arranger_songs_song, through: :arranger_songs end # app/models/lyricist_song.rb class LyricistSong < ApplicationRecord belongs_to :lyricist, class_name: "Artist", foreign_key: "artist_id" belongs_to :song end # app/models/composer_song.rb class ComposerSong < ApplicationRecord belongs_to :composer, class_name: "Artist", foreign_key: "artist_id" belongs_to :song end # app/models/arranger_song.rb class ArrangerSong < ApplicationRecord belongs_to :arranger, class_name: "Artist", foreign_key: "artist_id" belongs_to :song end
スキーマの状態
ruby
# db/schema.b ActiveRecord::Schema.define(version: 2021_09_29_115047) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" create_table "arranger_songs", force: :cascade do |t| t.bigint "arranger_id" t.bigint "song_id" t.index ["arranger_id"], name: "index_arranger_songs_on_arranger_id" t.index ["song_id"], name: "index_arranger_songs_on_song_id" end create_table "artists", force: :cascade do |t| t.string "name" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false end create_table "composer_songs", force: :cascade do |t| t.bigint "composer_id" t.bigint "song_id" t.index ["composer_id"], name: "index_composer_songs_on_composer_id" t.index ["song_id"], name: "index_composer_songs_on_song_id" end create_table "lyricist_songs", force: :cascade do |t| t.bigint "lyricist_id" t.bigint "song_id" t.index ["lyricist_id"], name: "index_lyricist_songs_on_lyricist_id" t.index ["song_id"], name: "index_lyricist_songs_on_song_id" end create_table "songs", force: :cascade do |t| t.string "name" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false end add_foreign_key "arranger_songs", "artists", column: "arranger_id" add_foreign_key "arranger_songs", "songs" add_foreign_key "composer_songs", "artists", column: "composer_id" add_foreign_key "composer_songs", "songs" add_foreign_key "lyricist_songs", "artists", column: "lyricist_id" add_foreign_key "lyricist_songs", "songs" end
試したこと
以下のような操作はちゃんとできました。
ruby
Song.create(name: "test1") Song.create(name: "test2") Artist.create(name: "a1") Artist.create(name: "a2")
中間テーブルを多分ちゃんと覗けています。。。
今はまだ中間テーブルは空です。
ruby
irb(main):012:0> Song.first.composer_songs Song Load (0.6ms) SELECT "songs".* FROM "songs" ORDER BY "songs"."id" ASC LIMIT $1 [["LIMIT", 1]] ComposerSong Load (0.7ms) SELECT "composer_songs".* FROM "composer_songs" WHERE "composer_songs"."song_id" = $1 [["song_id", 1]] => []
実現したいこと
以下のような状態を実現できるコントローラーを記述したいです。
しかし、どのようにしてSong.create(name: "test1")
のような
create
やupdate
の処理を記述したらいいのかわかりません。
私のような多対多のテーブルにおける、コントローラ(CRUD)の記述の仕方を教えていただきたいです。
よろしくお願いします。
まだ回答がついていません
会員登録して回答してみよう