如何从连接HABTM的表中获取属性

时间:2018-06-13 17:54:04

标签: ruby-on-rails ruby-on-rails-5

我的模特是

class User < ApplicationRecord
  has_many :recipients
  has_many :notifications, through: :recipients
end

class Recipient < ApplicationRecord
  belongs_to :user
  belongs_to :notification
end

class Notification < ApplicationRecord
  has_many :recipients

  scope :unread, -> { ??? }

  def read?
    # ???
  end
end

我的页面包含使用以下内容收到的通知列表:@user.notifications。但我需要检测哪些通知尚未读取。为此,我加入了表recipients,其中包含字段read_at

问题

我希望收到类似

的未读通知
user.notifications.unread

并检查是否未读取指定的通知

user.notifications.each { |n| n.read? }

在第一种情况下,我想获得查询

SELECT "notifications".*
FROM "notifications"
  INNER JOIN "recipients" ON "notifications"."id" = "recipients"."notification_id"
WHERE "recipients"."user_id" = $1
  AND "recipients"."read_at" IS NOT NULL

第二,我想避免其他疑问。

有可能吗?

1 个答案:

答案 0 :(得分:0)

User而不是Notification中添加范围,因为您的起点是user而不是通知。

class User < ApplicationRecord
  has_many :recipients
  has_many :notifications, through: :recipients

  def unread_notifications 
    notifications.where(recipients: { read_at: nil })
  end

  def read_notifications 
    notifications.where.not(recipients: { read: nil })
  end
end

user.notifications #=> all notifications
user.unread_notifications #=> all unread notifications of user
user.read_notifications #=> all read notifications of user

确定所有人是否阅读通知:

class Notification < ApplicationRecord
  has_many :recipients

  def read?
    recipients.all?(&:read_at)
  end
end