了解在 Rails 中创建播放列表的模型和关系

Understanding the Models and Relationships for Creating a Playlist in Rails

我正在使用 Rails 4.0 和 SQLite3。

我有四个模型:用户、专辑、歌曲、播放列表。我希望用户能够浏览歌曲列表并将它们添加到他们的播放列表之一。我似乎无法操纵这些关系来获取我想要的数据(例如,在页面上显示播放列表或通过 rails 控制台查询它们)。

到目前为止,我的模型关系如下所示:

class Playlist < ActiveRecord::Base
  belongs_to :user
  has_many :songs
end

class User < ActiveRecord::Base
  has_many :playlists
end 

class Album < ActiveRecord::Base
  has_many :songs
end

class Song < ActiveRecord::Base
  belongs_to :album
end

这种关系的构建是否错误?我只是想将歌曲添加到用户的播放列表,在用户个人资料中显示这些播放列表并允许用户查看每个独特的播放列表。

在对我自己的解决方案进行故障排除时,我在 rails 控制台中收到错误:undefined method val for Arel:Nodes 当我尝试执行 user.playlists.create(my_params_here) 来测试关系时。它开始创建列表,但随后因出现此错误而回滚。

感谢所有见解。谢谢

我认为播放列表和歌曲应该具有 多对多 关系,因为一个播放列表可以有很多歌曲,而一首歌曲可以属于多个播放列表。在这种情况下,您应该创建一个 has-many :through association.

class Playlist < ActiveRecord::Base
  belongs_to :user
  has_many :playlist_songs
  has_many :songs, through: :playlist_songs
end

class PlaylistSong < ActiveRecord::Base
  belongs_to :playlist
  belongs_to :song
end

class Song < ActiveRecord::Base
  belongs_to :album
  has_many :playlist_songs
  has_many :playlists, through: :playlist_songs
end

您可以使用 Rails 模型生成器生成模型及其关系:

rails g model playlist user:references:index
rails g model song album:references:index
rails g model playlist_song playlist:references:index song:references:index

注意:您可能希望在 运行 上述命令之前销毁 playlistsong 模型:

rails d model playlist
rails d model song

如果这不适合您,那么您将需要创建迁移以添加关系。

从您的控制台:

user = User.create(username: "bob", password: "password", email: "a@b.com")
album = Album.create
song = Song.create(album: album)
playlist = user.playlists.create
PlaylistSong.create(playlist: playlist, song: song)

听起来你需要一个歌曲的多态关联。 (http://guides.rubyonrails.org/association_basics.html#polymorphic-associations)

首先,您需要向歌曲 table 添加两个属性,一个是整数,一个是字符串。假设 :songable_id, :integer:songable_type, :string.

然后,:songable_type 将引用与 song 关联的模型,并且 :songable_id 将指定该模型的实例。因此 songsongable_type: "Playlist"songable_id: 1 将引用 Playlist.find(1).

以下是设置模型的方法:

class Playlist < ActiveRecord::Base
  belongs_to :user
  has_many :songs, as: :songable
end

class User < ActiveRecord::Base
  has_many :playlists
end 

class Album < ActiveRecord::Base
  has_many :songs, as: :songable
end

class Song < ActiveRecord::Base
  belongs_to :songable, polymorphic: true
end

如前所述添加外键here

正如@JordanDedels 评论的那样,它与外键有关。如果你有能力升级 Rails 到最新版本。而不是得到:

undefined method val for Arel:Nodes

你会得到这样的东西: ActiveRecord::UnknownAttributeError: unknown attribute 'user_id' for Playlist.