Сохранение первой пары ключ/значение в Postgres HSTORE через Rails Activerecord

Я работаю над своим приложением Ruby on Rails, и в этом приложении есть модель под названием «Пользователь». Эта модель имеет столбец базы данных (в моей базе данных Postgres), который называется «примечание». И это поле «примечание» имеет тип HSTORE. Он хранит хэш с дополнительной информацией об этом пользователе.

Я использую метод, который сохраняет значение параметра (params[:info]) в поле «примечание» с ключом «информация». Этот код работает.

def save_info_for_user(info)
    @user.remark = { :info => info }
    @user.save
  end  

И этот код не работает, когда поле базы данных пусто. Таким образом, только когда он содержит как минимум одну пару ключ/значение, можно сохранить новое значение, подобное этому.

  def save_info_for_user(info)
    @user.remark['info'] = info 
    @user.save
  end

Это дает следующую ошибку:

   > undefined method `[]=' for nil:NilClass

И этот код тоже не работает:

  def save_info_for_user(info)
    @user.remark[:info] = info 
    @user.save
  end

Выдает ту же ошибку

> undefined method `[]=' for nil:NilClass

И после некоторого тестирования я обнаружил, что 'remark[:info]' имеет другое значение, чем 'remark['info']'

Очень запутанно для меня.

Мой вопрос: Почему

@user.remark[:info] = info

дает эту ошибку. Он должен знать, что поле базы данных «примечание» является хэшем, потому что его тип определен как HSTORE?

Надеюсь, кто-нибудь сможет объяснить, что здесь происходит и как сделать этот метод перспективным.


person MDekker    schedule 28.09.2015    source источник


Ответы (2)


Он должен знать, что поле базы данных «примечание» является хэшем

Его тип — это хэш, но его текущее значениеNULL (это две совершенно разные вещи). В том смысле, что неизвестно. Даже не пустой хеш (потому что это было бы известное значение).

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

  def save_info_for_user(info)
    @user.remark ||= {}
    @user.remark['info'] = info 
    @user.save
  end
person Sergio Tulentsev    schedule 28.09.2015
comment
Спасибо Серхио! Звучит логично сейчас - person MDekker; 28.09.2015

Пожалуйста, попробуйте это. надеюсь, это сработает для вас.

def save_info_for_user(info)
  @user.remark = { "info" => info }
  @user.save
end  
person Suneel    schedule 28.09.2015