问题描述
我有几个对象都有一个 approved
字段.
I have several objects that all have an approved
field.
实现跨所有模型使用的范围的最佳方法是什么?
What would be the best way to implement a scope to use across all models?
例如,我有一个 sighting
对象和一个 comment
对象.它们都必须经过管理员的批准才能向公众开放.
For example, I have a sighting
object and a comment
object. They both have to be approved by an admin before being availalbe to the public.
那么如何创建一个范围,分别返回 comment.approved
和 sighting.approved
而不在每个模型上重复它?这是担忧的地方吗?
So how can I create a scope that returns comment.approved
as well as sighting.approved
respectively without repeating it on each model? Is this where concerns comes into play?
推荐答案
虽然如果您只想要范围功能,只需在每个模型中声明一个范围就可以了.如果您认为这会发生,使用 ActiveSupport::Concern
还可以让您添加其他方法.举个例子:
While just declaring a scope in each model is fine if you just want the scoping functionality. Using an ActiveSupport::Concern
will give you the ability to add additional methods as well if that's something you think is going to happen. Here's an example:
# /app/models/concerns/approved.rb
module Approved
extend ActiveSupport::Concern
included do
default_scope { where(approved: false) }
scope :approved, -> { where(approved: true) }
end
def unapprove
update_attribute :approved, false
end
end
class Sighting < ActiveRecord::Base
include Approved
end
class Comment < ActiveRecord::Base
include Approved
end
然后您可以进行诸如Sighting.approved
和Comment.approved
之类的调用,以获取相应的已批准记录列表.您还可以使用 unapprove
方法,并且可以执行诸如 Comment.approved.first.unapprove
之类的操作.
Then you can make calls like Sighting.approved
and Comment.approved
to get the appropriate list of approved records. You also get the unapprove
method and can do something like Comment.approved.first.unapprove
.
在这个例子中,我还包括了 default_scope
这意味着像 Sighting.all
或 Comment.all
这样的调用将只返回未经批准的物品.我只是将其作为示例包含在内,它可能不适用于您的实现.
In this example, I've also included default_scope
which will mean that calls like Sighting.all
or Comment.all
will return only unapproved items. I included this just as an example, it may not be applicable to your implementation.
这篇关于适用于多种型号的范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!