Rails 3 и Mongoid: проверка встроенных документов

Итак, у меня возникли проблемы с аутентификацией пользователя во встроенных документах. У меня есть два документа, один вложен в другой. В бизнесе много участников. Модели выглядят так:

class Member
  include Mongoid::Document

  field :username,        type: String
  field :password,           type: String
  embedded_in :business

  validates :username,  :presence => true, :uniqueness => true, :length => 5..60
end

class Business
  include Mongoid::Document

  field :name,            type: String
  embeds_many :members
end

Проблема в том, что он не проверяет уникальность имени пользователя в каждой модели. Когда я сохраняю участника в бизнесе, я могу сохранить тысячу участников с таким же именем. Это, конечно, не будет работать для хорошей системы аутентификации. Я использую Mongoid 2, Rails 3 и Ruby 1.9.


person Red    schedule 20.02.2012    source источник


Ответы (1)


Это нормальное поведение при использовании встроенных документов, как описано здесь: Проверка MongoID

validates_uniqueness_of

Убедитесь, что поле уникально в базе данных: обратите внимание, что для встроенных документов это будет проверять уникальность поля только в контексте родительского документа, а не всей базы данных.

Я думаю, вы хотите попробовать создать индекс в поле имени пользователя, который обеспечит уникальность среди всех объектов этой коллекции. Что-то вроде этого:

ensureIndex({username:1},{unique:true}); 

EDIT: если вы хотите, чтобы Mongo выдавала исключение, если существует документ с таким же значением индекса, вы должны избегать использования Mongo по шаблону «запустить и забыть». Это означает, что база данных не будет ждать ответа, когда вы выполняете операцию обновления/записи документа.

И вы хотите передать этот параметр: safe:true. При этом Mongo должен вызывать исключение, если по какой-либо причине документ не может быть вставлен.

person Nobita    schedule 20.02.2012
comment
Спасибо, я, должно быть, просто пропустил это. Поэтому я включил индекс, и он сработал. Единственная проблема заключается в том, что когда я сохраняю что-то с двумя одинаковыми именами пользователей, оно говорит «истина» (потому что оно проходит проверку), оно просто не сохраняется. Есть ли кто-нибудь, чтобы заставить функцию сохранения возвращать false? - person Red; 20.02.2012
comment
Это действительно хороший момент. Я провел некоторое исследование и считаю, что вы можете передать safe:true, и это поможет. Посмотрите на мою правку в ответе :) - person Nobita; 20.02.2012