Как создать модель ActiveRecord из кэша? - PullRequest
1 голос
/ 27 января 2012

Я добавляю кеширование в свое приложение на Rails, и одна из вещей, которые я делаю, это создание экземпляра модели ActiveRecord с использованием метода .new (вместо .create), чтобы он не пытался создать новую строку.

Например, если я добавлю это к моей модели:

def from_json(json)
  o = self.new
  ActiveSupport::JSON.decode(json).each do |k, v|
    # NOTE: I am doing this instead of sending all the params to .new
    #       because Rails won't let me bulk update protected attributes
    o.send(k + '=', v)
  end
  o
end

, а затем создаю экземпляр объекта из кэша:

o = Foo.from_json(redis.get(key))

Кажется, все работает хорошопока я не попытаюсь изменить поле:

o.bar = "spam and eggs"
o.save

Я получаю исключение, говорящее, что это дублирующая запись.

Как мне сообщить ActiveRecord, что этот факт ссылается на уже существующую строкув базе данных, чтобы он обновлял эту строку вместо броска и исключения?

1 Ответ

3 голосов
/ 28 января 2012

Ответы, которые мне нужны были найдены в lib/active_record/base.rb. Мне нужно инициализировать объект с new_record, установленным на false, и способ сделать это - выделить объект и затем инициализировать его с init_with. Обратите внимание, что вам нужно правильно сериализовать специальные serialized_attributes, используя их определенные кодеры.

Обратите внимание, что я использую Rail 3.1.

def serialize_for_cache
  h = self.attributes.clone
  self.class.serialized_attributes.each do |key, coder|
    h[key] = coder.dump(h[key])
  end
  ActiveSupport::JSON.encode(h)
end

def deserialize_from_cache(json)
  self.allocate.init_with('attributes' => ActiveSupport::JSON.decode(json))
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...