Configuração de persistência
Nesta página
Armazenamento de documentos
Por padrão, o Mongoid armazena documentos em uma coleção que é a forma pluralizada do nome da classe. Para a seguinte classe Person
, a coleção na qual o documento seria armazenado seria denominada people
.
class Person include Mongoid::Document end
Os nomes das classe de modelo não podem terminar com "s", porque será considerado a forma pluralizada da palavra. Por exemplo , "Status" seria considerado a forma plural de "Statu", o que causará alguns problemas conhecidos.
Esta é uma limitação do ActiveSupport::Inflector#classify
que o Mongoid usa para converter de nomes de arquivos e nomes de coleção para nomes de classe. Você pode superar isso especificando uma regra de inflexão personalizada para sua classe de modelo. Por exemplo, o código a seguir tratará do modelo denominado Status
.
ActiveSupport::Inflector.inflections do |inflect| inflect.singular("status", "status") end
A coleção dos documentos do modelo pode ser alterada no nível da classe se você desejar que eles permaneçam em outro lugar. Você também pode alterar o banco de dados de dados e o cliente em que o modelo persiste a partir dos padrões.
class Person include Mongoid::Document store_in collection: "citizens", database: "other", client: "analytics" end
A macro store_in
também pode receber lambdas - um caso comum para isso são aplicativos de vários inquilinos.
class Band include Mongoid::Document store_in database: ->{ Thread.current[:database] } end
Quando um documento é armazenado no banco de dados de dados, o objeto Ruby é serializado em BSON e tem uma estrutura como a seguinte:
{ "_id" : ObjectId("4d3ed089fb60ab534684b7e9"), "title" : "Sir", "name" : { "_id" : ObjectId("4d3ed089fb60ab534684b7ff"), "first_name" : "Durran" }, "addresses" : [ { "_id" : ObjectId("4d3ed089fb60ab534684b7e0"), "city" : "Berlin", "country" : "Deutschland" } ] }
Atributos de contexto de persistência
O Mongoid fornece métodos client_name
, database_name
e collection_name
em classes de modelo para determinar os nomes do cliente, banco de dados e coleção usados para persistência:
Band.client_name # => :default Band.database_name # => "mongoid" Band.collection_name # => :bands
Personalizado
Pode haver casos em que você deseja persistir documentos em fontes diferentes dos padrões ou com opções diferentes do padrão. A Mongoid fornece suporte em tempo de execução para isso, bem como suporte por modelo.
Opções de persistência em nível de modelo
Em uma base por modelo, você pode dizer para armazenar em um nome de coleção personalizado, um banco de dados de dados diferente ou um cliente diferente. O exemplo a seguir armazenaria a classe por padrão em uma coleção chamada "artists" no banco de banco de dados chamado "música", com o cliente "analytics".
Observe que o valor fornecido para a opção client
deve ser configurado em clients
em seu mongoid.yml.
class Band include Mongoid::Document store_in collection: "artists", database: "music", client: "analytics" end
Se nenhuma macro store_in
tivesse sido fornecida, o Mongoid armazenaria o modelo em uma coleção chamada "bandas" no banco de banco de dados padrão no cliente padrão.
Opções de persistência de tempo de execução
É possível alterar o cliente, o banco de dados de dados e a collection, bem como qualquer uma das opções do cliente MongoDB , usadas para persistência de um grupo de operações, usando o método with
em uma classe ou instância de modelo:
Band.with(database: "music-non-stop") do |klass| klass.create(...) band = Band.first Band.create(...) end Band.with(collection: "artists") do |klass| klass.delete_all Band.delete_all end band.with(client: :tertiary) do |band_object| band_object.save! band.save! end
O método with
cria um contexto de persistência temporário e um cliente MongoDB para ser utilizado para operações no contexto. Durante o bloqueio, o contexto de persistência na classe de modelo ou instância em que o with
foi chamado é alterado para o contexto de persistência temporário. Por conveniência, a classe de modelo ou instância em que o with
foi chamado é produzida no bloco.
O contexto de persistência temporária se aplica a queries e gravações.
Deve-se ter cuidado ao realizar operações de persistência em diferentes contextos de persistência. Por exemplo, se um documento for salvo em um contexto de persistência temporário, ele poderá não existir no contexto de persistência padrão, falhando nas atualizações subsequentes:
band = Band.new(name: "Scuba") band.with(collection: "artists") do |band_object| band_object.save! end # This will not save - updates the collection "bands" which does not have # the Scuba band band.update_attribute(likes: 1000) # This will update the document. band.with(collection: "artists") do |band_object| band_object.update_attribute(likes: 1000) end
A partir do Mongoid 6.0, o método with
deve sempre ser chamado com um bloco, e o contexto de persistência temporário existe somente durante o bloco. Isso ocorre porque um novo cliente é criado sob as cobertas com as opções passadas para with
. Para garantir que esse cliente seja fechado e que seus recursos associados sejam liberados, o escopo em que esse cliente pode ser usado deve ser bem definido.
Substituição global
Se você quiser mudar o contexto de persistência para todas as operações em tempo de execução, mas não quiser usar com todo o seu código, o Mongoid oferece a capacidade de fazer isso como nível de cliente e banco de dados globalmente. Os métodos para isso são Mongoid.override_client
e Mongoid.override_database
. Um caso útil para isso são aplicativos internacionalizados que armazenam informações para diferentes localidades em diferentes bancos de dados ou clientes, mas o esquema em cada um permanece o mesmo.
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 acima, todas as operações persistentes seriam armazenadas no banco de dados alternativo para todas as operações restantes neste thread. É por isso que a solicitação posterior define a substituição como nula - ela garante que as solicitações subsequentes sem parâmetros locais usem a opção padrão.
O contexto de persistência se aplica a operações de leitura e escrita. Por exemplo, leituras secundárias podem ser realizadas da seguinte forma:
Band.with(read: {mode: :secondary}) do Band.count end
Acesso do cliente e da collection
Se você quiser descer ao nível do driver para executar operações, você pode pegar o cliente mongo ou coleção a partir do modelo ou instância de documento :
Band.mongo_client band.mongo_client Band.collection band.collection
A partir daqui, você também tem as mesmas opções de persistência de tempo de execução usando o #with
do cliente:
client = Band.mongo_client.with(write: { w: 0 }, database: "musik") client[:artists].find(...)
Você também pode substituir as opções :read ou :write na collection usando as collections #with
:
collection_w_0 = Band.collection.with(write: { w: 0 }) collection_w_0[:artists].find(...)