Rails has_many :通过关联问题
Rails has_many :through association issue
我有一个包含三个模型的应用程序 - 用户、相册和评论。目前,评论是我的加入 table。
一个用户有很多评论,通过评论有很多相册。一张专辑有很多评论,并且通过评论有很多用户。用户属于相册和评论。
我的问题是:有没有办法重新安排这些关联,使两个 has_many :through 关联在不同的模型上工作?因为我目前无法调用 album.user。它必须是 'album.users',然后显示一长串与相册完全无关的用户。
我需要一个 has_many、一个 belongs_to 和两个 has_many:通过与这三个模型的关联。这甚至可能吗,还是我需要添加其他模型,例如流派或评论?
任何建议都有帮助,我会 post 下面是我的模型:
专辑
class Album < ApplicationRecord
has_many :reviews, :dependent => :destroy
has_many :users, through: :reviews # incorrect
has_one_attached :avatar
accepts_nested_attributes_for :reviews
validates_presence_of :artist
validates_presence_of :title
validate :unique_title_by_artist
scope :with_recent_reviews, -> { includes(:reviews).where(reviews: { date: [(Date.today - 7.days)..Date.tomorrow] }) }
private
def unique_title_by_artist
if Album.where('lower(title) = ? AND artist = ?', self.title.downcase, self.artist).count > 0
@errors.add(:title, "must be unique to artist")
end
end
end
评论
class Review < ApplicationRecord
belongs_to :album, optional: true
belongs_to :user
validates_presence_of :content
validates :title, presence: true, uniqueness: true
validates :date, presence: true
accepts_nested_attributes_for :album
scope :recent, -> { where("date(date) >= ?", Date.today - 7.days) } #scope for album
end
用户
require 'securerandom'
class User < ApplicationRecord
has_secure_password
validates :email, uniqueness: true, presence: true, format: { with: URI::MailTo::EMAIL_REGEXP }
validates :name, uniqueness: true, length: {in: 3..20}, presence: true
has_many :reviews
has_many :albums, through: :reviews
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_initialize do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.name
user.email = auth.info.email
user.password = SecureRandom.urlsafe_base64
user.oauth_token = auth.credentials.token
user.oauth_expires_at = Time.at(auth.credentials.expires_at)
user.save!
end
end
end
您可以将user_id
(整数)添加到albums
table,然后您可以跟踪相册的用户
在模型中添加
class Album < ApplicationRecord
has_many :reviews, :dependent => :destroy
has_many :reviewers, through: :reviews, source: :user
belongs_to :user
end
class User < ApplicationRecord
has_many :reviews
has_many :reviewed_albums, through: :reviews, source: :album
has_many :albums
end
users
到 reviews
是 reviewers
(评论相册的用户)
我有一个包含三个模型的应用程序 - 用户、相册和评论。目前,评论是我的加入 table。 一个用户有很多评论,通过评论有很多相册。一张专辑有很多评论,并且通过评论有很多用户。用户属于相册和评论。
我的问题是:有没有办法重新安排这些关联,使两个 has_many :through 关联在不同的模型上工作?因为我目前无法调用 album.user。它必须是 'album.users',然后显示一长串与相册完全无关的用户。
我需要一个 has_many、一个 belongs_to 和两个 has_many:通过与这三个模型的关联。这甚至可能吗,还是我需要添加其他模型,例如流派或评论?
任何建议都有帮助,我会 post 下面是我的模型:
专辑
class Album < ApplicationRecord
has_many :reviews, :dependent => :destroy
has_many :users, through: :reviews # incorrect
has_one_attached :avatar
accepts_nested_attributes_for :reviews
validates_presence_of :artist
validates_presence_of :title
validate :unique_title_by_artist
scope :with_recent_reviews, -> { includes(:reviews).where(reviews: { date: [(Date.today - 7.days)..Date.tomorrow] }) }
private
def unique_title_by_artist
if Album.where('lower(title) = ? AND artist = ?', self.title.downcase, self.artist).count > 0
@errors.add(:title, "must be unique to artist")
end
end
end
评论
class Review < ApplicationRecord
belongs_to :album, optional: true
belongs_to :user
validates_presence_of :content
validates :title, presence: true, uniqueness: true
validates :date, presence: true
accepts_nested_attributes_for :album
scope :recent, -> { where("date(date) >= ?", Date.today - 7.days) } #scope for album
end
用户
require 'securerandom'
class User < ApplicationRecord
has_secure_password
validates :email, uniqueness: true, presence: true, format: { with: URI::MailTo::EMAIL_REGEXP }
validates :name, uniqueness: true, length: {in: 3..20}, presence: true
has_many :reviews
has_many :albums, through: :reviews
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_initialize do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.name
user.email = auth.info.email
user.password = SecureRandom.urlsafe_base64
user.oauth_token = auth.credentials.token
user.oauth_expires_at = Time.at(auth.credentials.expires_at)
user.save!
end
end
end
您可以将user_id
(整数)添加到albums
table,然后您可以跟踪相册的用户
在模型中添加
class Album < ApplicationRecord
has_many :reviews, :dependent => :destroy
has_many :reviewers, through: :reviews, source: :user
belongs_to :user
end
class User < ApplicationRecord
has_many :reviews
has_many :reviewed_albums, through: :reviews, source: :album
has_many :albums
end
users
到 reviews
是 reviewers
(评论相册的用户)