Docs Menu
Docs Home
/ /

Alcance

En esta guía, aprenderá a implementar ámbitos en sus modelos Mongoid. Los ámbitos ofrecen una forma práctica de reutilizar criterios de filtro comunes. Para obtener más información sobre la creación de criterios de filtro, consulte Especifique una guía de consulta de documentos.

Puede implementar alcances en su aplicación para reducir el código repetido si está aplicando los mismos criterios a la mayoría de las consultas.

Los ámbitos con nombre son criterios definidos al cargar la clase y referenciados por un nombre proporcionado. Al igual que los criterios de filtro, se cargan de forma diferida y son encadenables.

Este ejemplo define una Band modelo que incluye los siguientes ámbitos con nombre:

  • japanese: Coincide con documentos en los que el valor del campo country es "Japan"

  • rock: Coincide con documentos en los que el valor del campo genre incluye "rock"

class Band
include Mongoid::Document
field :country, type: String
field :genres, type: Array
scope :japanese, ->{ where(country: "Japan") }
scope :rock, ->{ where(:genres.in => [ "rock" ]) }
end

Luego, puedes hacer queries utilizando los ámbitos nombrados. La siguiente query utiliza los ámbitos nombrados para coincidir con documentos en los que el valor del campo country es "Japan" y el valor del campo genre incluye "rock":

Band.japanese.rock

Puede definir Proc objetos y bloques en ámbitos con nombre para que acepten parámetros y amplíen la funcionalidad.

Este ejemplo define un modelo Band que incluye el alcance based_in, que coincide con los documentos en los que el valor del campo country es el valor especificado que se pasa como parámetro:

class Band
include Mongoid::Document
field :name, type: String
field :country, type: String
scope :based_in, ->(country){ where(country: country) }
end

Luego, puedes realizar consultas utilizando el ámbito based_in, como se muestra en el siguiente código:

Band.based_in("Spain")

Mongoid le permite definir un ámbito que ensombrece un método de clase existente, como se muestra en el siguiente ejemplo:

class Band
include Mongoid::Document
def self.on_tour
true
end
scope :on_tour, ->{ where(on_tour: true) }
end

Puede indicarle a Mongoid que genere un error cuando un ámbito sobrescribe un método de clase existente estableciendo la opción de configuración scope_overwrite_exception en true.

Para obtener más información sobre esta configuración, consulte la guía de configuración de la aplicación.

Los ámbitos predeterminados son útiles cuando se aplican los mismos criterios a la mayoría de las consultas. Al definir un ámbito predeterminado, se especifican estos criterios como predeterminados para cualquier consulta que utilice el modelo. Los ámbitos predeterminados devuelven Criteria objetos.

Para crear un ámbito predeterminado, debe definir el método default_scope en su clase de modelo.

El siguiente código define el método default_scope en el modelo Band para recuperar únicamente documentos en los que el valor del campo active sea true:

class Band
include Mongoid::Document
field :name, type: String
field :active, type: Boolean
default_scope -> { where(active: true) }
end

Luego, cualquier consulta en el modelo Band prefiltra los documentos en los que el valor active es true.

Al especificar un alcance predeterminado, se inicializan los campos de los nuevos modelos con los valores dados en el alcance predeterminado si esos valores son literales, como valores booleanos o números enteros.

Nota

Conflictos de campo y alcance

Si proporciona un valor predeterminado en una definición de campo y en el ámbito predeterminado, el valor en el ámbito predeterminado tendrá prioridad, como se muestra en el siguiente ejemplo:

class Band
include Mongoid::Document
field :name, type: String
field :on_tour, type: Boolean, default: true
default_scope ->{ where(on_tour: false) }
end
# Creates a new Band instance in which "on_tour" is "false"
Band.new

No se recomienda utilizar notación de puntos para hacer referencia a campos anidados en ámbitos predeterminados. Esto puede hacer que Mongoid inicialice campos inesperados en nuevos modelos.

Por ejemplo, si define un ámbito predeterminado que hace referencia al campo tour.year, se inicializa un nuevo modelo con el campo tour.year en lugar de un campo tour con un objeto anidado que contiene un campo year.

Al realizar consultas, Mongoid interpreta correctamente la notación de puntos y coincide con los documentos en los que un campo anidado tiene el valor especificado.

Si define un ámbito predeterminado en un modelo que forma parte de una asociación, debe recargar la asociación para que se aplique el ámbito. Esto es necesario cuando se modifica un valor de un documento en la asociación que afecta su visibilidad al aplicar el ámbito.

Este ejemplo utiliza los siguientes modelos:

class Label
include Mongoid::Document
field :name, type: String
embeds_many :bands
end
class Band
include Mongoid::Document
field :name, type: String
field :active, default: true
embedded_in :label
default_scope ->{ where(active: true) }
end

Supongamos que crea un modelo Label que contiene una asociación con un Band cuyo valor de active es true. Al actualizar el campo active a false, Mongoid lo carga a pesar del alcance predeterminado. Para ver los documentos de la asociación con el alcance aplicado, debe llamar al operador reload.

El siguiente código demuestra esta secuencia:

label = Label.new(name: "Hello World Records")
band = Band.new(name: "Ghost Mountain")
label.bands.push(band)
label.bands # Displays the Band because "active" is "true"
band.update_attribute(:active, false) # Updates "active" to "false"
# Displays the "Ghost Mountain" band
label.bands # => {"_id":"...","name":"Ghost Mountain",...}
# Won't display "Ghost Mountain" band after reloading
label.reload.bands # => nil

Mongoid trata los criterios en un ámbito predeterminado de la misma manera que cualquier otra condición de consulta. Esto puede generar un comportamiento inesperado al usar los métodos or y nor.

Los siguientes ejemplos demuestran cómo Mongoid interpreta las consultas en modelos con un alcance predeterminado:

class Band
include Mongoid::Document
field :name
field :touring
field :member_count
default_scope ->{ where(touring: true) }
end
# Combines the condition to the default scope with "and"
Band.where(name: 'Infected Mushroom')
# Interpreted query:
# {"touring"=>true, "name"=>"Infected Mushroom"}
# Combines the first condition to the default scope with "and"
Band.where(name: 'Infected Mushroom').or(member_count: 3)
# Interpreted query:
# {"$or"=>[{"touring"=>true, "name"=>"Infected Mushroom"}, {"member_count"=>3}]}
# Combines the condition to the default scope with "or"
Band.or(member_count: 3)
# Interpreted query:
# {"$or"=>[{"touring"=>true}, {"member_count"=>3}]}

Para obtener más información sobre las operaciones lógicas, consulte Operaciones lógicas en la guía Especificar una consulta.

Puede indicarle a Mongoid que no aplique el alcance predeterminado utilizando el operador unscoped, como se muestra en los siguientes ejemplos:

# Inline example
Band.unscoped.where(name: "Depeche Mode")
# Block example
Band.unscoped do
Band.where(name: "Depeche Mode")
end

Puede utilizar el método with_scope para cambiar el alcance predeterminado en un bloque en tiempo de ejecución.

El siguiente modelo define el ámbito mexican denominado:

class Band
include Mongoid::Document
field :country, type: String
field :genres, type: Array
scope :mexican, ->{ where(country: "Mexico") }
end

Puede utilizar el método with_scope para establecer el ámbito nombrado mexican como el ámbito predeterminado en tiempo de ejecución, como se muestra en el siguiente código:

Band.with_scope(Band.mexican) do
Band.all
end

Mongoid trata los métodos de clase que devuelven objetos Criteria como ámbitos. Puedes realizar consultas usando estos métodos de clase, como se muestra en el siguiente ejemplo:

class Band
include Mongoid::Document
field :name, type: String
field :touring, type: Boolean, default: true
def self.touring
where(touring: true)
end
end
Band.touring

Para obtener más información sobre cómo personalizar sus modelos Mongoid, consulte las guías Modele sus datos.

Volver

Especifica un query

En esta página