如何在我的 show 方法中调用 join table?更新

How do I call a join table in my show method? UPDATED

[更新,向下滚动查看解决方案]

我正忙于使用 Rails 开发音乐流媒体应用程序,但遇到了一个基本问题。我不知道如何称呼我的关节 table.

这是我的流程:

我有 3 个 table 与播放列表和曲目有关

create_table "tracks", force: :cascade do |t|
    t.string "title"
    t.text "description"
    t.string "artist"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.bigint "album_id", null: false
    t.bigint "user_id", null: false
    t.string "photo"
    t.string "track"
    t.index ["album_id"], name: "index_tracks_on_album_id"
    t.index ["user_id"], name: "index_tracks_on_user_id"
  end

create_table "playlists", force: :cascade do |t|
    t.string "playlist_title"
    t.text "playlist_description"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.bigint "user_id", null: false
    t.index ["user_id"], name: "index_playlists_on_user_id"
  end

create_table "playlists_tracks", id: false, force: :cascade do |t|
    t.bigint "playlist_id", null: false
    t.bigint "track_id", null: false
  end

期望的结果 -> 在 Show.html.erb 中渲染轨道,其中轨道的 playlist_id 为 x

我当前的代码在 playlists_controller.rb

中看起来像这样
def show
    @playlist = Playlist.find(params[:id])
    @track = Track.where(playlist_id: params[:id])
end

结果是一个错误说

column tracks.playlist_id does not exist
LINE 1: SELECT "tracks".* FROM "tracks" WHERE "tracks"."playlist_id"...

如果我在模式中转到我的轨道 table,它找不到 playlist_id 值是有道理的,因为 table 没有 playlist_id列。

然而,在我的 playlists_tracks 关节 table 中有一个 playlist_id 以及一个 track_id.

不明白的地方>>

当用户添加曲目时,我知道曲目信息正在添加到曲目中 table。但是 playlists_tracks table 中没有添加任何信息。我期望当用户将曲目添加到播放列表时,这是将现有曲目关联到 a/many 播放列表的时间。我还没有创建将曲目添加到播放列表的功能。

现在我只是想查看特定播放列表的显示页面,其中包含将呈现相关曲目的代码。我当前的代码在曲目 table 中找不到 playlist_id,因为它不存在。我的第一个想法是更改我的 SHOW 方法,以便它搜索 playlists_tracks table 而不是曲目 table.

但是,我的语法没有意义。我应该像下面这样称呼我的 playlists_tracks table 吗?有大写的 P 和奇异的曲目?

新的显示方式:

def show
        @playlist = Playlist.find(params[:id])
        @playlist_track = Playlists_track.where(playlist_id: params[:id])
    end

希望我描述的篇幅对您有所帮助,不要矫枉过正! 感谢您的宝贵时间。

为了进一步参考,这里是我的关联模型

class Playlist < ApplicationRecord
    has_many :tracks, through: :playlists_tracks
    has_many :tags, through: :playlists_tags
    belongs_to :user

    validates :playlist_title, presence: true, length: { in: 1..20 }
    validates :playlist_description, presence: true, length: { in: 10..60 }

    has_one_attached :photo
end

class Track < ApplicationRecord
    belongs_to :album
    belongs_to :user
    has_many :playlists, through: :playlists_tracks
    has_many :tags, through: :tags_tracks

    validates :title, presence: true, length: { in: 1..20 }
    validates :description, presence: true, length: { in: 10..60 }
    has_one_attached :photo
    has_one_attached :track
end

[更新]

  1. 我缺少一个 PlaylistTrack 模型
  2. 我的 has_many 联想需要更正
  3. 播放列表控制器显示方法已更改语法

新模型

class PlaylistTrack < ApplicationRecord
belongs_to :track
belongs_to :playlist
end

添加到架构

  create_table "playlist_tracks", force: :cascade do |t|
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.bigint "playlist_id", null: false
    t.bigint "track_id", null: false
    t.index ["playlist_id"], name: "index_playlist_tracks_on_playlist_id"
    t.index ["track_id"], name: "index_playlist_tracks_on_track_id"
  end

更正播放列表模型

class Playlist < ApplicationRecord
    has_many :playlist_tracks
    has_many :tracks, through: :playlist_tracks
    has_many :tags, through: :playlist_tags
    belongs_to :user

    validates :playlist_title, presence: true, length: { in: 1..20 }
    validates :playlist_description, presence: true, length: { in: 10..60 }

    has_one_attached :photo
end

更正轨道模型

class Track < ApplicationRecord
    belongs_to :album
    belongs_to :user
    has_many :playlist_tracks
    has_many :playlists, through: :playlist_tracks
    has_many :tags, through: :tags_tracks

    validates :title, presence: true, length: { in: 1..20 }
    validates :description, presence: true, length: { in: 10..60 }
    has_one_attached :photo
    has_one_attached :track
end

更正显示方法

def show
    @playlist = Playlist.find(params[:id])
    @tracks = @playlist.tracks
end

加入 table 与 N:N 的关系是如此混乱。我预计会出现更多错误,因为我在控制台中的测试并不乐观(用曲目播种播放列表)但至少播放列表显示页面现在正在呈现。

希望这对您有所帮助,如果您有任何建议,请在下方留言:)

创建答案以包含代码片段: 我将假设“playlist_tracks”table 是使用 foreign keys/references 创建的,它连接到相关的 table:

class CreatePlaylistTracks < ActiveRecord::Migration[6.0]
  def change
    create_table :playlist_tracks do |t|
      t.references :playlist, null: false, foreign_key: true
      t.references :track, null: false, foreign_key: true

      t.timestamps
    end
  end
end

您需要调整您的模型(同时假设您定义了 PlaylistTrack 模型,其中包含 belongs_tos):

class Playlist < ApplicationRecord
    has_many :playlist_tracks, inverse_of: :playlist
    has_many :tracks, through: :playlist_tracks
    has_many :tags, through: :playlist_tags
    belongs_to :user

    validates :playlist_title, presence: true, length: { in: 1..20 }
    validates :playlist_description, presence: true, length: { in: 10..60 }

    has_one_attached :photo
end

然后在控制器中,你应该能够做到:

def show
    @playlist = Playlist.find(params[:id])
    @track = @playlist.tracks
end

你能看出这是否有所不同吗?

期望的结果 -> 在 Show.html.erb 中渲染轨道,其中轨道的 playlist_id 为 x

def show
    @playlist = Playlist.find(params[:id])
    @tracks = @playlist.tracks
end

如果只需要轨道,另一种解决方案:

def show
  @tracks = Track.includes(:playlists).where(playlists: { id: params[:id] })
end