Rails - Mongoid: недавно добавленные поля в модели дают ноль для старых объектов данных - PullRequest
3 голосов
/ 22 июня 2011

У меня модель выглядит следующим образом:

class User
  include Mongoid::Document
  field :name
end

После сохранения нескольких пользовательских объектов в базе данных я добавил еще несколько полей:

class User
  include Mongoid::Document
  include Mongoid::Timestamps::Created
  field :name
  field :birthdate
end

Теперь я ожидаю, что смогу использовать следующий фрагмент:

@user = User.all
@user.each do |u|
   puts u.name
   puts u.birthdate.strftime(#someFormat)
   puts u.created_at.strftime(#someFormat)
end

К сожалению, поскольку мои старые user объекты не имеют birthdate ключей, я получаю эту ошибку: strftime called on nil class.

Вопрос:

  • Как я могу обрабатывать такие случаи с Mongoid? В MySQL при добавлении столбца он добавляется и к старым строкам. Но если я вижу в MongoDB, он не добавляет новые поля в качестве ключей для старых данных.
  • Эта проблема также существует с полем created_at, поскольку старые данные также не имеют этого поля.

Я ищу хороший способ решить эту проблему, проверяя условия nil каждый раз, и это не масштабируемая опция, поскольку количество полей будет продолжать увеличиваться.

Ответы [ 2 ]

3 голосов
/ 23 июня 2011

Вы также можете добавить значение по умолчанию для вашего нового поля, которое даст всем вашим старым записям запасное значение.

class User
  include Mongoid::Document
  include Mongoid::Timestamps::Created

  field :name
  field :birthdate, :type => Date, :default => Date.new(1970,1,1)
end

Вы можете обновить ваши модели, в которых отсутствуют значения created_at, но просто запустите что-то простое в консоли rails:

User.all.each{ |u| u.update_attributes(:created_at => Time.now) if u.created_at.nil? }
1 голос
/ 22 июня 2011

1) Вы можете проверить значение nil для этих полей:

@user = User.all
@user.each do |u|
   puts u.name
   puts u.birthdate.strftime(#someFormat) if u.birthdate
   puts u.created_at.strftime(#someFormat) if u.created_at
end

2) Вы можете обновить все ваши старые модели с фактическими значениями, отличными от nil для этих полей.Вы можете сделать это с помощью обновления mondodb (подробнее здесь ) или написав скрипт ruby ​​следующим образом:

User.all.select{|u| u.birthdate.nil? || u.created_at.nil?}.each do |u|
  u.update_attributes(:birthdate => Date.today, :created_at => Time.now)
end

атрибуты birthdate и creation_at заполнены примерами.

...