在其他方法中重用rails范围条件的DRY解决方案?

时间:2012-01-26 13:45:31

标签: ruby-on-rails ruby-on-rails-3 activerecord

在Rails 3.1中,给出了这个模型:

class Subscripion < ActiveRecord::Base
    scope :active, lambda {
        where("start_date is not ? AND end_date >= ?", nil, Date.today)
    }

    def active?
      self.class.active.exists?(self)
    end
end

到目前为止,这是我能想到的最干燥的解决方案,因为它不会重复active?方法中的条件。

但有两个缺点:

  • 鉴于Subscription实例,不需要数据库查询来确定它是否处于活动状态。我们可以根据其属性!start_date.nil? && end_date >= Date.today来检查。对exists?的调用会导致额外的数据库查询。
  • 如果在exists?范围内调用active之前更改了初始订阅实例,则结果不是我们想要的结果,因为exists?会忽略该实例并直接查询数据库。 / LI>

关于更好的解决方案的任何想法,仍然在一个地方定义条件?

1 个答案:

答案 0 :(得分:1)

我相信活跃吗?方法实现不好,因为它将加载所有活动订阅,然后查看列表中的self。更好的方法是这样的:

def active?
  self.class.active.where(id: self.id).present?
end

此实现仅使用COUNT查询检查数据库。

无论如何,我相信对于主动更有意义吗?方法与你所写的条件(!start_date.nil?&amp;&amp; end_date&gt; = Date.today),因为它是反映当前实例的真实状态的唯一方法。