Is it possible to define a scope for a non db column

╄→гoц情女王★ 提交于 2021-01-29 11:50:25

问题


We have a method in our model occurs_on?

Enrollment.first.occurs_on?(Date.current)

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

回答1:


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.

Example

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)

This of course has a few limitations

  • 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.



回答2:


No, what you're suggesting isn't possible because scopes are just used to modify the SQL query generated by ActiveRecord.

However, you can probably create a scope that achieves what you're looking for. Whilst you may not be familiar/comfortable with it, and it will likely require you to write code specific to your DB of choice, you can almost certainly replicate the logic you require for identifying whether your Enrollment occurs on a specific date within your DB query.




回答3:


This seems to work. I'm sure it's inefficient but it's giving us correct results and pagination works on this

scope :occurs_today, -> { where(id: all.select { |s| s.occurs_on?(Date.current) }.map(&:id)) }


来源:https://stackoverflow.com/questions/63927562/is-it-possible-to-define-a-scope-for-a-non-db-column

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!