Menu Docs
Página inicial do Docs
/ / /
Mongoid
/

Mongoid 9.0

Nesta página

Esta página descreve alterações e melhorias significativas no Mongoid 9.0. A lista completa de versões está disponível no GitHub e no JIRA; consulte as versões do GitHub para obter notas de versão detalhadas e o JIRA para obter a lista completa de problemas corrigidos em cada versão, incluindo correções de bugs.

Para coincidir com o lançamento do Mongoid 9.0 um novo utilitário de linha de comando para criar, atualizar, gerenciar e manter aplicativos Rails também foi disponibilizado ao público em geral!

railsmdb facilita o trabalho com o MongoDB a partir da linha de comando através de geradores comuns com os quais os desenvolvedores Ruby on Rails já estão familiarizados.

Por exemplo, você pode utilizar o railsmdb para gerar stubs para novos modelos Mongoid:

$ bin/railsmdb generate model person

Isso criará um novo modelo em app/models/person.rb:

class Person
include Mongoid::Document
include Mongoid::Timestamp
end

Você também pode especificar os campos do modelo:

# bin/railsmdb generate model person name:string birth:date
class Person
include Mongoid::Document
include Mongoid::Timestamp
field :name, type: String
field :birth, type: Date
end

Você pode instruir o gerador a tornar o novo modelo uma subclasse de outro, passando a opção --parent :

# bin/railsmdb generate model student --parent=person
class Student < Person
include Mongoid::Timestamp
end

E se você precisar armazenar seus modelos em uma collection diferente da que pode ser inferida a partir do nome do modelo, você pode especificar --collection:

# bin/railsmdb generate model course --collection=classes
class Course
include Mongoid::Document
include Mongoid::Timestamp
store_in collection: 'classes'
end

Para obter mais informações, consulte o Repositório do GitHub .

Mongoide 9 exige Ruby 2.7 ou mais recente ou JRuby 9.4. Versões anteriores do Ruby e JRuby não são suportadas.

Mongoide 9 exige Rails 6.0 ou mais recente. Versões anteriores do Rails não são suportadas.

A classe obsoleta Mongoid::Errors::InvalidStorageParent foi removida.

O Mongoid 8.x e versões mais antigas permitem que o usuário defina around_* callbacks para documentos incorporados. A partir de 9.0 estas chamadas de resposta são ignoradas e não serão executadas. Um aviso será impresso no console se esses retornos de chamada forem definidos.

Se desejar restaurar o comportamento antigo, você pode definir Mongoid.around_embedded_document_callbacks como true em seu aplicativo.

Observação

Habilitar around_* chamadas de resposta para documentos incorporados não é recomendado, pois pode causar SystemStackError exceções quando um documento tiver muitos documentos incorporados. Consulte MONGOID-5658 para obter mais detalhes.

O método for_js está obsoleto e será removido no Mongoid 10.0.

Alteração significativa: as seguintes opções de configuração são removidas no Mongoid 9.0. Certifique-se de remover todas as referências a eles do seu aplicativo. Se você estava usando config.load_defaults 8.1 antes de atualizar, não sofrerá nenhuma alteração de comportamento. Consulte as notas de versão anteriores para saber o significado de cada opção.

  • :use_activesupport_time_zone

  • :broken_aggregables

  • :broken_alias_handling

  • :broken_and

  • :broken_scoping

  • :broken_updates

  • :compare_time_by_ms

  • :legacy_attributes

  • :legacy_pluck_distinct

  • :legacy_triple_equals

  • :object_id_as_json_oid

  • :overwrite_chained_operators

Além disso, suporte para config.load_defaults versões 7.5 e anterior foi descartado (você deve usar um mínimo da versão 8.0.)

Alteração significativa: a seguinte funcionalidade obsoleta foi removida:

  • O módulo Mongoid::QueryCache foi removido. Substitua quaisquer usos 1-for-1 por Mongo::QueryCache. O método Mongoid::QueryCache#clear_cache deve ser substituído por Mongo::QueryCache#clear. Todos os outros métodos e submódulos recebem nomes idênticos. Consulte a documentação do cache de query do driver para obter mais detalhes.

  • Object#blank_criteria? método é removido (anteriormente estava obsoleto).

  • Document#as_json :compact opção é removida. Ligue para `#compact no objeto Hash retornado.

  • A classe obsoleta Mongoid::Errors::InvalidStorageParent foi removida.

No Mongoid 8.x e no método touch mais antigo deixa os modelos no estado alterado:

# Mongoid 8.x behaviour
band = Band.create!
band.touch
band.changed? # => true
band.changes # => {"updated_at"=>[2023-01-30 13:12:57.477191135 UTC, 2023-01-30 13:13:11.482975646 UTC]}

A partir de 9.0 Mongoid agora limpa corretamente o estado alterado após usar o método touch .

# Mongoid 9.0 behaviour
band = Band.create!
band.touch
band.changed? # => false
band.changes # => {}

O Mongoid agora suporta o modo sandbox do console Rails. Se o console Rails foi iniciado com o sinalizador --sandbox , o Mongoid iniciará uma transação no cliente :default antes de abrir o console. Esta transação não será confirmada; portanto, todos os comandos executados no console usando o cliente :default não serão mantidos no banco de dados.

Observação

Se você executar comandos no modo sandbox usando qualquer outro cliente que não seja o padrão, essas alterações persistirão como de costume.

Mongoide 9.0 introduz uma nova API de transações inspirada no ActiveRecord:

Band.transaction do
Band.create(title: 'Led Zeppelin')
end
band = Band.create(title: 'Deep Purple')
band.transaction do
band.active = false
band.save!
end

Consulte a documentação das transações para obter mais detalhes.

O Mongoid 8.x e versões mais antigas permitem ao usuário especificar o contexto de persistência para um documento incorporado (usando a macro store_in ). Em Mongoid 9.0 essas configurações são ignoradas para documentos incorporados; um documento incorporado agora sempre usa o contexto de persistência de seu documento principal.

Ao realizar queries, agora é possível ignorar a lógica de coerção do tipo Mongoid usando a classe wrapper Mongoid::RawValue . Isso pode ser útil quando os dados legados no banco de dados forem de um tipo diferente da definição de campo.

class Person
include Mongoid::Document
field :age, type: Integer
end
# Query for the string "42", not the integer 42
Person.where(age: Mongoid::RawValue("42"))

Ao tentar acessar um campo em uma instância de modelo que foi excluído com os métodos de projeções de query .only ou .without quando a instância foi carregada, o Mongoid agora criará um erro Mongoid::Errors::AttributeNotLoaded .

Band.only(:name).first.label
#=> raises Mongoid::Errors::AttributeNotLoaded
Band.without(:label).first.label = 'Sub Pop Records'
#=> raises Mongoid::Errors::AttributeNotLoaded

Nas versões anteriores do Mongoid, as mesmas condições gerariam um ActiveModel::MissingAttributeError. Verifique seu código para quaisquer usos específicos do Mongoid desta classe e altere-os para Mongoid::Errors::AttributeNotLoaded. Observe também que AttributeNotLoaded herda de Mongoid::Errors::MongoidError, enquanto ActiveModel::MissingAttributeError não.

Ao fazer query de um campo de hora usando um valor de data, o Mongoid agora considera corretamente Time.zone para executar a conversão de tipo.

class Magazine
include Mongoid::Document
field :published_at, type: Time
end
Time.zone = 'Asia/Tokyo'
Magazine.gte(published_at: Date.parse('2022-09-26'))
#=> will return all results on or after Sept 26th, 2022
# at 0:00 in Asia/Tokyo time zone.

Nas versões anteriores do Mongoid, o código acima ignorava a Time.zone (independentemente da configuração :use_activesupport_time_zone , agora removida) e sempre usava o fuso horário do sistema para executar a conversão de tipo.

Observe que, em versões anteriores do Mongoid, a conversão de data para hora durante as operações de persistência já estava correta usando o fuso horário.

Quando a opção touch: false está definida em uma relação embedded_in , chamar o método #touch em um documento filho incorporado não invocará #touch em seu documento pai.

class Address
include Mongoid::Document
include Mongoid::Timestamps
embedded_in :mall, touch: false
end
class Mall
include Mongoid::Document
include Mongoid::Timestamps
embeds_many :addresses
end
mall = Mall.create!
address = mall.addresses.create!
address.touch
#=> updates address.updated_at but not mall.updated_at

Além disso, o método #touch foi otimizado para executar uma operação de persistência por documento pai, mesmo ao usar vários níveis de documentos incorporados aninhados.

A atualização de um subdocumento incorporado agora tocará automaticamente no pai, a menos que você defina explicitamente touch: false na relação:

class Address
include Mongoid::Document
include Mongoid::Timestamps
embedded_in :mall, touch: false
end

Para todas as outras associações, o padrão permanece touch: false.

Mongoide 8.1 adicionou a opção :replace ao método #upsert . Esta opção foi usada para especificar se o documento existente deve ou não ser atualizado ou substituído.

Mongoide 9.0 inverte o padrão desse sinalizador de true => false.

Isso significa que, por padrão, o Mongoid 9 atualizará o documento existente e não o substituirá.

Antes do Mongoide 9.0, a mutação do campo _id se comportou de forma inconsistente dependendo se o documento era de nível superior ou incorporado e dependendo de como a atualização foi executada. A partir de 9.0, alterar o campo _id agora criará uma exceção quando o documento for salvo, se o documento tiver sido persistido anteriormente.

Mongoide 9.0 também introduz um novo sinalizador de recurso, immutable_ids, que é padronizado para true.

Mongoid::Config.immutable_ids = true

Quando definido como falso, o comportamento mais antigo e inconsistente é restaurado.

Foi adicionado suporte para usar nomes de campos com nomes alternativos nas seguintes opções da macro index : partial_filter_expression, weights, wildcard_projection.

class Person
include Mongoid::Document
field :a, as: :age
index({ age: 1 }, { partial_filter_expression: { age: { '$gte' => 20 } })
end

Observação

A expansão de aliases de nome de campo em opções de índice como partial_filter_expression é executada de acordo com o comportamento do servidor MongoDB 6.0. Versões futuras do servidor podem mudar a forma como interpretam essas opções, e a funcionalidade do Mongoid pode não suportar essas alterações.

Quando BSON 4 ou anterior estiver presente, qualquer campo declarado como BSON::Decimal128 retornará um valor BSON::Decimal128 . No entanto, quando BSON 5 está presente, qualquer campo declarado como BSON::Decimal128 retornará um valor de BigDecimal por padrão.

class Model
include Mongoid::Document
field :decimal_field, type: BSON::Decimal128
end
# under BSON <= 4
Model.first.decimal_field.class #=> BSON::Decimal128
# under BSON >= 5
Model.first.decimal_field.class #=> BigDecimal

Se você precisar de valores literais BSON::Decimal128 com BSON 5, poderá instruir o Mongoid a permitir campos literais BSON::Decimal128 :

Model.first.decimal_field.class #=> BigDecimal
Mongoid.allow_bson5_decimal128 = true
Model.first.decimal_field.class #=> BSON::Decimal128

Observação

A opção allow_bson5_decimal128 só tem efeito sob BSON 5 e posterior. O BSON 4 e as versões anteriores ignoram totalmente a configuração.

Quando conectado ao MongoDB Atlas, o Mongoid agora suporta a criação e remoção de índices de pesquisa. Você pode fazer isso programaticamente, por meio da API Mongoid::SearchIndexable:

class SearchablePerson
include Mongoid::Document
search_index { ... } # define the search index here
end
# create the declared search indexes; this returns immediately, but the
# search indexes may take several minutes before they are available.
SearchablePerson.create_search_indexes
# query the available search indexes
SearchablePerson.search_indexes.each do |index|
# ...
end
# remove all search indexes from the model's collection
SearchablePerson.remove_search_indexes

Se você não estiver conectado ao MongoDB Atlas, as definições do índice de pesquisa serão ignoradas. Tentar criar, enumerar ou remover índices de pesquisa resultará em um erro.

Também há tarefas de coleta disponíveis, para conveniência:

# create search indexes for all models; waits for indexes to be created
# and shows progress on the terminal.
$ rake mongoid:db:create_search_indexes
# as above, but returns immediately and lets the indexes be created in the
# background
$ rake WAIT_FOR_SEARCH_INDEXES=0 mongoid:db:create_search_indexes
# removes search indexes from all models
$ rake mongoid:db:remove_search_indexes

Time.configured retornou o objeto de tempo agrupando o fuso horário configurado ou a classe Ruby Time padrão. Isso permitia que você executasse uma query de um valor de hora mesmo que nenhum fuso horário tivesse sido configurado.

O Mongoid agora exige que você defina um fuso horário se pretende fazer qualquer coisa com valores de tempo (incluindo o uso de carimbos de data/hora em seus documentos). Qualquer uso de Time.configured deve ser substituído por Time.zone.

# before:
puts Time.configured.now
# after:
puts Time.zone.now
# or, better for finding the current Time specifically:
puts Time.current

Se você não definir um fuso horário, verá erros em seu código relacionados a valores de nil . Se você estiver usando o Rails, o fuso horário padrão já está definido como UTC. Se você não estiver usando o Rails, você pode definir um fuso horário no início do seu programa como este:

Time.zone = 'UTC'

Isso definirá o fuso horário como UTC. Você pode ver todos os nomes de fuso horário disponíveis executando o seguinte comando:

$ ruby -ractive_support/values/time_zone \
-e 'puts ActiveSupport::TimeZone::MAPPING.keys'

Considere o seguinte código:

record = Model.with(collection: 'other_collection') { Model.first }
record.update(field: 'value')

Antes do Mongoide 9.0, isso poderia falhar silenciosamente ao executar a atualização, porque as opções de armazenamento (aqui, a especificação de uma coleção alternativa para o modelo) não seriam lembradas pelo registro. Assim, o registro seria carregado de " other_collection ", mas, quando atualizado, tentaria procurar e atualizar o documento na coleção padrão do Modelo. Para fazer isso funcionar, você teria que especificar a coleção explicitamente para cada atualização.

A partir do Mongoid 9.0, os registros criados ou carregados sob opções de armazenamento explícitas, lembrarão essas opções (incluindo um cliente nomeado, um banco de dados diferente ou uma collection diferente).

Se você precisar do comportamento legado (pré-9.0), você pode habilitá-lo com a seguinte sinalização:

Mongoid.legacy_persistence_context_behavior = true

Este sinalizador é padronizado como falso no Mongoid 9.

Esta seção será para correções de bugs e melhorias menores:

  • O .unscoped método agora também limpa escopos declarados usando .with_scope MONGOID-5214.

  • Ao desenvolver um String para um BigDecimal (ou seja, ao consultar um BigDecimal campo com um String objeto ), se o map_big_decimal_to_decimal128 sinalizador definido como true, a conversão retornará um BSON::Decimal128 e não um String MONGOID-5484.

  • Novo erro criado Mongoid::Errors::InvalidEstimatedCountCriteria para ao chamar estimated_document_count em uma classe de documento com um escopo padrão MONGOID-4960.

  • O Mongoid agora usa leituras primárias para validações em todos os casos MONGOID-5150.

  • Adicionado suporte para chaves de símbolo em hashes de tradução de campo localizados MONGOID-5334.

  • Adicionada opção curinga de índice MONGOID-5388.

  • Com o map_big_decimal_to_decimal128 sinalizador definido como falso, demongoizing um valor não numérico e não de cadeia de caracteres que implementa :to_d retornará uma cadeia de caracteres em vez de um BigDecimal MONGOID-5507.

  • Suporte adicionado para serializar e desserializar valores BSON::ObjectId quando passados como argumentos do ActiveJob MONGOID-5611.

← Atualizando o Mongoid