我有一个模特
Email
和实例方法
def sent_to_user?(user)
self.who_to == user
end
其中who_to是另一个执行某些复杂内容的实例方法。
在后台还有更多的东西在那里,所以我不能轻易将它变成一个活跃的记录查询。
我想做类似的事情:
scope :sent_to_user, -> (user) { sent_to_user?(user)}
@user.emails.sent_to_user
并仅返回那些为" sent_to_user返回true的电子邮件?'
尝试了
scope :sent_to_user, -> (user) { if sent_to_user?(user)}
....等。
不太确定如何构建范围/类方法
答案 0 :(得分:7)
你不能(至少不应该)以这种方式使用范围。范围用于返回ActiveRecord关系,其他范围可以链接到该关系。如果要使用作用域,则应生成必要的SQL以在数据库中执行过滤。
如果要在Ruby中过滤结果并返回数组,则应使用类级方法,不范围:
class Email < ActiveRecord::Base
def self.sent_to_user(user)
select { |record| record.sent_to_user?(user) }
end
end
答案 1 :(得分:0)
你应该在ActiveRecord逻辑中编写who_to,比如
范围:sent_to_user, - &gt; (用户){joins(:recipient)where(recipient_id:user.id)}
答案 2 :(得分:0)
假设用户has_many :emails
可以执行以下操作:
class User < ActiveRecord::Base
has_many :emails
# ...
def emails_sent_to_user
emails.select { |e| e.sent_to_user?(self) }
end
end
答案 3 :(得分:0)
有趣的是,我制定了一个方法来进行检查,这有点像黑客,但在这种情况下工作,可能对某人有用。 接受的解决方案的问题,虽然它是基于我所描述的限制来实现它的唯一方法,但性能可能会非常缓慢。
我现在正在使用:
scope :sent_to_user, -> (user) {"json_email -> 'to' ILIKE ?", "%#{user.email)}%"}
其中“json_email”是解析为json的电子邮件对象(这是我们将它们存储在数据库中的方式)。这减少了使用Mail gem的需要,并大大提高了性能。