Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/installation/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 3 在范围中添加条件返回(能够根据条件链接范围中的范围)_Ruby On Rails 3 - Fatal编程技术网

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 问题是,在作用域内,我不知道如何链接其他作用域,我的意思是,“deu occ”必须根据其他条件链接,但现在这将无法正常工作,因为它将只返回一个作用域,而不是将“deu occ”链接到第一个条件。我怎样才能做到这一点


谢谢

好的,我看一下你的代码没有什么问题。最好的做法是不要使用您的母语言作为模型和方法名称的来源

解决问题的基本方法是将逻辑移到一个方法中,并将作用域/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”,你用我的母语用代码提问是绝对正确的,我会考虑进一步的问题。我对服务对象一无所知,我将尝试按照您的示例进行更多搜索,以使我的模型更小。回答得好!