是否可以为非db列定义范围 [英] Is it possible to define a scope for a non db column

查看:48
本文介绍了是否可以为非db列定义范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们的模型中有一个方法 occurs_on?

We have a method in our model occurs_on?

Enrollment.first.occurs_on?(Date.current)

,如果注册日期为Date,则返回true(否则为false).注册有一个重复的时间表,如果不使用Ruby进行计算,就无法对 occurs_on?进行数据库查询.一切正常,但是这使我们无法进行分页.是否可以定义不依赖于数据库列的作用域?例如类似

which returns true if an enrollment falls on a Date (and false if not). Enrollments have a recurring schedule and it's not possible to do a db query for occurs_on? without doing calculations in Ruby. It's all working fine but this is throwing off our pagination. Is it possible to define a scope that doesn't depend on a database column? For example something like

scope :occurs_today, -> { occurs_on?(Date.current) }

我希望这是可能的,例如,我们可以使用分页并链接范围

I'm hoping it's possible so we can use pagination and also chain the scope, for example

Enrollment.active.occurs_today

推荐答案

Jon编写的所有内容都是正确的,但是 scopes 基本上只是模型类上的类方法.这意味着您可以根据用于分页的库来复制类似的行为.

All what Jon wrote is correct, however, scopes are basically only class methods on your model class. This means you could replicate a similar behaviour depending on which library you use for pagination.

示例

class Enrollment
  scope :active -> { where(active: true) }

  def self.occurs_today
    records = select { |record| record.occurs_on?(Date.current) }

    # https://github.com/kaminari/kaminari#paginating-a-generic-array-object
    Kaminari.paginate_array(records, total_count: count)
  end
end

Enrollment.active.occours_today.page(2)

这当然有一些局限性

  • 您仍然需要从数据库中加载所有记录,并在Ruby中对其进行过滤.分页的主要好处之一是加载较少的数据,所以这不是您真正应该做的.
  • 作用域"不返回ActiveRecord关系,例如一个数组,因此您必须使用该方法作为最后一个方法,因为 Enrollment.occurs_today.active 会抛出一个 undefined active active .
  • You still need to load all records from the database and filter them in Ruby. One main benefit of pagination is to load less data so it's not really what you should do.
  • The 'scope' does not return an ActiveRecord relationship but e.g. an Array so you have to use the method as the last one because Enrollment.occurs_today.active will throw a undefined method active.

这篇关于是否可以为非db列定义范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆