如何在我的 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
[更新]
- 我缺少一个 PlaylistTrack 模型
- 我的 has_many 联想需要更正
- 播放列表控制器显示方法已更改语法
新模型
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_to
s):
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
[更新,向下滚动查看解决方案]
我正忙于使用 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
[更新]
- 我缺少一个 PlaylistTrack 模型
- 我的 has_many 联想需要更正
- 播放列表控制器显示方法已更改语法
新模型
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_to
s):
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