Jef*_*cke 2 ruby scope ruby-on-rails
似乎无法解决这个问题.我有一个消息模型如下
Message
# content:string
# original_id:integer
# sender_id:integer
# receiver_id:integer
has_one :reply, class_name: "Message", foreign_key: "original_id"
belongs_to :original, class_name: "Message"
Run Code Online (Sandbox Code Playgroud)
每条消息只能有一个回复,回复消息将有相应的原始消息.
我想要做的是创建一个范围或类方法,允许我在一个批处理中提取已回复的消息,在另一个批处理中提取未提取的消息.
就像是
# return messages that have a reply present
def self.replied
where(reply.present?)
end
# return messages that have no reply
def self.unreplied
where(reply.nil?)
end
Run Code Online (Sandbox Code Playgroud)
所以我可以链接方法,最终用它来拉消息
user1.messages.replied
Run Code Online (Sandbox Code Playgroud)
它目前不起作用,因为我不能使用where子句,除非它是一个DB列......所以我在考虑在DB中添加一个"replied"布尔列,所以我可以使用where子句但是可能有一个解决方案对此,我只是没想到.一个范围有一个lambda?我现在卡住了.
任何帮助非常感谢
找到那些已经回复的内容相当简单:
scope :replied, joins(:reply)
Run Code Online (Sandbox Code Playgroud)
因为任何没有回复的内容都会被INNER JOIN过滤掉.要找到那些没有回复的东西有点复杂 - 您可以使用LEFT JOIN或EXISTS子查询来完成此任务. includes是一种强制LEFT JOIN的简单方法:
scope :unreplied, includes(:reply).
where(replies_messages: {id: nil}).
where(original_id: nil)
Run Code Online (Sandbox Code Playgroud)
EXISTS子查询可能更有效,但写入更复杂(此时),因为它涉及调用Arel表(或Squeel).对于大多数情况,LEFT JOIN将"足够好",并且includes是一种强制API使用它的快速而肮脏的方法.
| 归档时间: |
|
| 查看次数: |
1366 次 |
| 最近记录: |