Ruby on rails 3 在范围中添加条件返回(能够根据条件链接范围中的范围)
我在最近添加的新权限代码中有一个带条件的重复代码。它不是从一开始就设计的,所以有点凌乱:Ruby on rails 3 在范围中添加条件返回(能够根据条件链接范围中的范围),ruby-on-rails-3,Ruby On Rails 3,我在最近添加的新权限代码中有一个带条件的重复代码。它不是从一开始就设计的,所以有点凌乱: @usuarios = Usuario.menores_de_edad.con_autorizacion(params[:autorizacion]).con_nombre(params[:nombre]) # master puede ver todos, así que ignora los permisos if !usuario_actual.es_master? if usuario_actu
@usuarios = Usuario.menores_de_edad.con_autorizacion(params[:autorizacion]).con_nombre(params[:nombre])
# master puede ver todos, así que ignora los permisos
if !usuario_actual.es_master?
if usuario_actual.permiso.blank?
# Si es admin y no tiene permisos establecidos
@usuarios = Usuario.where(id: nil)
else
# Lee de que niveles puedes mostrar los usuarios
@usuarios = @usuarios.del_nivel(usuario_actual.permiso.niveles)
end
end
if usuario_actual.es_admin_occ?
@usuarios = @usuarios.de_occ
end
我希望通过以下方式将其作为一个范围:
@usuarios = Usuario.menores_de_edad.con_autorizacion(params[:autorizacion]).con_nombre(params[:nombre])
@usuarios = @usuarios.permitibles(usuario_actual)
我怎样才能让它工作?我目前有:
class Usuario < ActiveRecord::Base
scope :permitibles, lambda{ |usuario_actual|
# master can see everything, so, don't scope anything at all
if !usuario_actual.es_master?
if usuario_actual.permiso.blank?
# return nothing if you don't have permissions
where(id: nil)
else
# this is a scope
del_nivel(usuario_actual.permiso.niveles)
end
if usuario_actual.es_admin_occ?
# this is a scope
de_occ
end
end
}
end
类Usuario谢谢 好的,我看一下你的代码没有什么问题。最好的做法是不要使用您的母语言作为模型和方法名称的来源 解决问题的基本方法是将逻辑移到一个方法中,并将作用域/sql链起来。以下是概念证明:
scope :menores_de_edad, ->() {where(something: true)}
scope :del_nivel, ->(params) {where(field: param)}
scope :de_occ, ->() { ... }
def self.we_are_chaining_scopes
result = self.scoped
if !usuario_actual.es_master?
if usuario_actual.permiso.blank?
# return nothing if you don't have permissions
result = result.menores_de_edad
else
# this is a scope
result = result.del_nivel(usuario_actual.permiso.niveles)
end
if usuario_actual.es_admin_occ?
# this is a scope
result = result.de_occ
end
end
result
end
您可以通过为此查询创建服务对象,使其更加完善。粗略的例子:
class SpecificQuery
def initialize(relation = Model.scoped)
@relation = relation
end
private
def scoped_to(&block)
@relation = @relation.instance_eval(&block)
end
def scoped_behavior_method_one(param)
scoped_to { where(:something: param) }
end
def scoped_behavior_method_two(param)
scoped_to { ... }
end
end
然后,您可以很好地链接作用域+您正在封装不一定属于您的模型的逻辑。另外,编写规范更容易:)我希望这会有所帮助。谢谢!,我缺少的部分是“self.scoped”,你用我的母语用代码提问是绝对正确的,我会考虑进一步的问题。我对服务对象一无所知,我将尝试按照您的示例进行更多搜索,以使我的模型更小。回答得好!