Menu Docs

Configuração de persistência

Neste guia, você aprenderá como o Mongoid persiste dados em seu banco de dados e coleções. A configuração de persistência refere-se às configurações que controlam como o Mongoid armazena dados no MongoDB. Isso inclui o cliente, o banco de dados e a coleção onde os documentos de uma classe de modelo são armazenados, bem como outras opções de configuração, como preferências de leitura e gravação. Este guia fornece métodos e exemplos que você pode usar para acessar e atualizar a configuração de persistência de uma classe de modelo.

Observação

O termo "cliente" refere-se a uma configuração de host definida em clients no seu arquivo mongoid.yml. A maioria dos aplicativos utiliza um único cliente denominado default.

Por padrão, o Mongoid armazena documentos em uma collection cujo nome é a forma pluralizada do nome da classe representativa. No exemplo a seguir , para a classe Restaurant , a coleção correspondente é denominada restaurants. Para a classe Person , a coleção correspondente é denominada people.

class Restaurant
include Mongoid::Document
end
class Person
include Mongoid::Document
end

No entanto, as regras padrão de pluralização nem sempre funcionam. Por exemplo, suponha que seu modelo seja denominado Rey. A forma plural desta palavra em espanhol é reyes, mas o nome da coleção padrão é reys.

Você pode criar uma nova regra de pluralização para sua classe de modelo chamando o ActiveSupport::Inflector::Inflections.plural método de instância e passando as formas singular e plural do nome da classe . O exemplo a seguir especifica reyes como o plural de rey:

ActiveSupport::Inflector.inflections do |inflect|
inflect.plural("rey", "reyes")
end

Como resultado, o Mongoid armazena Rey documentos de classe de modelo na collection reyes.

Observação

Estrutura do documento BSON

Quando o Mongoid armazena um documento em um banco de dados, ele serializa o objeto Ruby para um documento BSON que tem a seguinte estrutura:

{
"_id" : ObjectId("4d3ed089fb60ab534684b7e9"),
"title" : "Sir",
"name" : {
"_id" : ObjectId("4d3ed089fb60ab534684b7ff"),
"first_name" : "Durran"
},
"addresses" : [
{
"_id" : ObjectId("4d3ed089fb60ab534684b7e0"),
"city" : "Berlin",
"country" : "Deutschland"
}
]
}

Cada classe de modelo contém os seguintes métodos, que você pode usar para recuperar informações sobre onde o Mongoid persiste o modelo:

  • client_name: Recupera o nome do cliente

  • database_name: Recupera o nome do banco de dados

  • collection_name: recupera o nome da coleção

O exemplo a seguir mostra como recuperar e imprimir os nomes do cliente, banco de dados e coleção onde os documentos da classe Band persistem:

puts Band.client_name
puts Band.database_name
puts Band.collection_name
default
my_bands
bands

O Mongoid fornece opções em nível de modelo e de tempo de execução para personalizar sua configuração de persistência. As seções a seguir descrevem estas opções.

Suponha que você queira armazenar os documentos do seu modelo em uma coleção com um nome diferente da forma pluralizada do nome da classe do modelo. Você pode usar a macro store_in para alterar a coleção, banco de dados ou cliente onde o Mongoid armazena os documentos de um modelo. O exemplo a seguir mostra como usar a macro store_in para armazenar documentos da classe Person em uma coleção chamada citizens no banco de dados other em um cliente chamado analytics:

class Person
include Mongoid::Document
store_in collection: "citizens", database: "other", client: "analytics"
end

A macro store_in também pode aceitar uma função Lambda. Isso é útil se você quiser definir um contexto de persistência com valores que não podem usar uma string constante.

Talvez você queira usar esse padrão em um aplicação multilocatário, em que vários usuários compartilham acesso comum a um aplicação. Ao usar um Lambda, você pode definir um contexto de persistência com base em informações locais do thread atual para que os usuários não possam acessar os dados uns dos outros.

O exemplo a seguir armazena documentos em um banco de dados determinado por uma variável thread-local:

class Band
include Mongoid::Document
store_in database: ->{ Thread.current[:database] }
end

Você pode usar o método with em uma classe ou instância de modelo para alterar a configuração de persistência de um modelo para um grupo de operações durante o tempo de execução.

Chame o método with em uma classe ou instância de modelo e passe opções que definem um contexto de persistência. Você pode chamar o método with de duas maneiras:

  • with(context, options): context é uma instância de Mongoid::PersistenceContext e options é um Hash que representa um conjunto personalizável de opções.

  • with(options): options é um Hash que representa um conjunto personalizável de opções.

Em seguida, utilize um bloco para definir as operações que deseja executar no contexto especificado. O contexto que você define existe somente enquanto o código no bloco é executado.

Por padrão, o Mongoid armazena documentos para a classe Band em uma coleção chamada bands. O exemplo de código a seguir usa o método with para usar temporariamente um cliente, um banco de dados e uma coleção diferentes para executar operações nos documentos da classe Band:

class Band
include Mongoid::Document
field :name, type: String
field :likes, type: Integer
end
# Creates document in 'bands' collection in 'music-non-stop' database within
# default cluster
Band.with(database: "music-non-stop") do |band_class|
band_class.create(name: "Medusa and the Polyps")
end
# Deletes all documents in 'artists' collection within default database
Band.with(collection: "artists") do |band_class|
band_class.delete_all
end
band = Band.new(name: "Japanese Breakfast")
# Perform operations on tertiary cluster
band.with(client: :tertiary) do |band_object|
band_object.save!
band.save!
end

Observação

Definir clientes

No exemplo anterior, você deve definir o cluster tertiary em clients em seu arquivo mongoid.yml.

Importante

Escopo do bloco

Você deve chamar o método with com um bloco. Isso ocorre porque o Mongoid usa as opções que você passa para o método para criar um novo cliente em segundo plano. Um bloco define o escopo desse cliente para que ele possa ser fechado e seus recursos liberados.

Você também pode passar as opções de configuração do método with para operações de leitura ou escrita. As configurações se aplicam apenas ao tipo de operação especificado.

O exemplo a seguir usa o método with para especificar o uso do nó secundário para todas as operações de leitura dentro do bloco.

Band.with(read: {mode: :secondary}) do
Band.count
# This write operation runs in the
# new persistence context, but is
# not affected by the read preference.
Band.create(name: "Metallica")
end

Observação

Garantindo consistência em contextos

Quando você executa uma operação em um contexto, o Mongoid não executa automaticamente a mesma operação em contextos diferentes. Por exemplo, se você inserir um documento de modelo Band na collection artists, o mesmo documento não será inserido na collection bands.

Em exemplos anteriores nesta seção, você alterou o contexto de persistência apenas no escopo de um bloco. Você pode usar o Mongoid para definir globalmente um contexto de persistência personalizado que todas as operações em seu programa usam. Isto permite a você alterar o contexto de persistência para todas as operações no tempo de execução sem chamar repetidamente o método with.

Você pode usar os seguintes métodos para definir globalmente o contexto de persistência em seu programa:

  • Mongoid.override_client: Mongoid executa todas as operações no cliente especificado .

  • Mongoid.override_database: Mongoid executa todas as operações no banco de dados especificado .

No exemplo de código a seguir, o aplicação armazena informações para diferentes localidades em diferentes bancos de dados. O código mostra como utilizar o método Mongoid.override_database para configurar globalmente o contexto de persistência baseado no locale:

class BandsController < ApplicationController
before_action :switch_database
after_action :reset_database
private
def switch_database
I18n.locale = params[:locale] || I18n.default_locale
Mongoid.override_database("my_db_name_#{I18n.locale}")
end
def reset_database
Mongoid.override_database(nil)
end
end

No exemplo anterior , o Mongoid executa todas as outras operações neste thread em um banco de dados alternativo determinado pelo locale. Como a macro after_action define a opção de substituição como nil, as solicitações subsequentes sem alterações na configuração de persistência usam a configuração padrão.

Você pode acessar o cliente ou a coleção de um modelo ou instância de documento usando os métodos de classe mongo_client e collection:

Band.mongo_client
band.mongo_client
Band.collection
band.collection

Ao usar esses métodos, você também pode definir opções de persistência de tempo de execução chamando o with método, semelhante aos exemplos na seção Opções de persistência de tempo de execução.

O exemplo de código a seguir acessa o cliente usado pela classe de modelo Band . Em seguida, ele usa o método with no cliente para escrever no banco de dados music , definindo a opção de gravação w como 0 para não exigir confirmação de gravação.

Band.mongo_client.with(write: { w: 0 }, database: "music") do |client|
client[:artists].find(...)
end

Você pode substituir as opções :read e :write em uma coleção utilizando o método with. O exemplo a seguir mostra como usar o método with para definir a opção de gravação w como 0:

Band.collection.with(write: { w: 0 }) do |collection|
collection[:artists].find(...)
end

Para obter mais informações sobre os métodos mencionados neste guia, consulte a seguinte documentação da API: