Mongoid #2: Документы
марта 16, 2011 | Published in Базы данных | 6 Comments
Данная статья является переводом официальной документации:
Документы — основные объекты в Mongoid и любой объект, который сохраняется в базу данных должен включать в себя через include Mongoid::Document. Представлением документа в MongoDB является BSON-объект, который очень похож на хэш в Ruby или объект формата JSON. Документы могут храниться в своих собственных коллекциях в базе данных или могут быть включены в другие документы таким образом имея некую степень вложенности.
Объявление документов в Mongoid
Рассмотрим простой класс — модель человека. У каждого человека должны быть имя, фамилия и отчество. Мы можем объявить эти атрибуты человека объявив соответствующие поля (поле — field) в объекте представляющем человека. В Mongoid поля, по умолчанию, имеют тип String.
#person.rb class Person include Mongoid::Document field :first_name field :middle_initial field :last_name end
Для полей с другим типом данных, тип данных должен быть указан явно при помощи опции :type. В настоящее время, в Mongoid существуют следующие типы полей: Array, BigDecimal, Boolean, Date, DateTime, Float, Hash, Integer, String, Symbol, Time и любой объект, который наследуется от Mongoid::Document. Поля типа BigDecimal будут конвертироваться в/из String в базе данных.
#person.rb class Person include Mongoid::Document field :birthday, :type => Date end
Поля могут иметь значения по умолчанию, которые устанавливаются при помощи опции :default во время объявления поля. Запомните, что значения по умолчанию должны соответствовать типам полей для которых они назначаются, кроме того, полями могут принимать лямбды.
#person.rb class Person include Mongoid::Document field :blood_alcohol_level, :type => Float, :default => 0.0 end
Вы можете отменить тип уникального поля _id в коллекции с помощью ключевого слова identity. В следующем примере, поле _id будет иметь тип String. Это очень полезно если вы хотите, чтобы в поле _id хранилось что-то другое вместо идентификатора сохраненного объекта.
#person.rb: class Person include Mongoid::Document identity :type => String end
Примеры документов
Экземпляр документа создается с помощью вызова метода .new для класса документа и передачи в него хэша с атрибутами. Кроме того вы можете передать блок кода.
Если вы установили в настройках соединения с базой данных для опции allow_dynamic_fields значение false, то есть отключили ее, и для атрибута в хэше не определено соответствующее поле, или он не объявлен ассоциацией, тогда будет возвращена ошибка.
person = Person.new(:first_name => "Ludwig", :last_name => "Beethoven") person = Person.new do |p| p.first_name = "Ludwig" p.last_name = "Beethoven" end
Контроль доступа к полям
Вы можете защитить атрибуты от массового определения используя attr_protected, или предоставить противоположную возможность с помощью attr_accessible. Это необходимо в тех случаях, когда чувствительные поля не могут быть случайным образом установлены через передачу формы или аналогичным образом.
Когда используется attr_protected для определенного поля, то все остальные поля будут доступны для массового определения атрибутов.
class Person include Mongoid::Document field :first_name attr_protected :_id end
Когда используется attr_accessible для определенного поля, то все остальные поля будут не способны быть установленными через массовое определение атрибутов.
class Person include Mongoid::Document field :first_name field :last_name attr_accessible :first_name, :last_name end
Динамические атрибуты
По умолчанию Mongoid поддерживает динамические атрибуты для получения и установки их значений, и сохранения в документе даже если поле для их хранения не определено. Mongoid не совсем снисходителен в использовании method_missing при обращении к динамическим атрибутам.
Когда происходит связь с динамическими атрибутами, то применяются следущие правила:
- Если поле соответствующее атрибуту существует в документе, Mongoid предоставит вам доступ с помощью стандартных методов аксессоров. Например, рассматривая человека, который имеет атрибут «gender» (пол) который установлен в документе:
person[:gender] = "Male" person.gender # => вернет "Male" person.gender = "Female" #=> установит атрибуту gender значение "Female"
- Если атрибут еще не существует в документе, Mongoid не предоставит вам стандартных методов аксессоров и при попытке обращения к атрибуту вернет ошибку. В этом случае вы должны использовать другие предоставляемые методы аксессоры: ([] и []=) или (read_attribute и write_attribute):
person[:gender] # => вернет nil person[:gender] = "Male" # => установит атрибуту gender значение "Male" person.read_attribute(:age) # => вернет nil person.write_attribute(:age, 35) # => установит атрубуту age значение 35
Зарезервированные названия
Если вы объявите поле в вашем документе, которое конфликтует с именем метода в Mongoid, то вы получите ошибку. Чтобы увидеть список недопустимых имен для полей, вы можете взглянуть на Mongoid.destructive_fields.
марта 16, 2011 at 14:16 (#)
«Поля должны также иметь значения по умолчанию, которые устанавливаются при помощи опции :default во время объявления поля.» Именно «должны»? Или могут иметь значения по умолчанию?…
марта 16, 2011 at 19:58 (#)
Значения по умолчанию могут иметь и если имеют, то эти значения долны быть того же типа, что и поля. Уже поправил.
марта 16, 2011 at 22:48 (#)
Автор, без обид, но можно было бы вложить хоть немного труда разработчика а не простой перевод. Я эту документацию перечитал в оригинале вдоль и поперек, но у меня возникали вопросы, относительно, к примеру, динамических полей, о которых документация сухо описывает как прочитать или записать, но нет объяснения как получить список доступных полей для списка документов.Думаю у многих тоже возникают вопросы, и вместо того чтоб потратить 2-3 часа вашего времени чтоб разобраться, и описать действительно полезные вещи, вы выложили статью имеющую ценность только для людей которые не читают на английском и не умеют пользоваться онлайн переводчиком.
Хотелось бы чуть больше качества от блога со стороны разработки, а не исключительно переводы официальных доков.
марта 17, 2011 at 00:38 (#)
Валентин, я пока сам только изучаю Mongoid, поэтому каким-либо опытом поделиться не могу. Но, если вы читали вводный пост, до долны были увидить там слово о том, что я обязательно буду писать авторские темы по работе с mongoid и MongoDB.
октября 19, 2011 at 18:58 (#)
ну и где???)))))
октября 19, 2011 at 20:08 (#)
В данный момент с Mongoid не работаю. Чуть позже начну писать на эту тему, сейчас не могу — много других дел.