ActiveRecord не обновляет / сохраняет, но показывает, что поле было изменено в консоли (db говорит иначе) - PullRequest
3 голосов
/ 03 ноября 2011
content = Content.find(params[:content_id])
content.body.insert(start_index, span_open)
content.save!
content.body.insert(end_index + span_open.length, span_open)
content.save!

puts "=========================================="
c = Content.find(params[:content_id])
puts c.body

так что выше, это то, что я пытался сделать.много сохранений .. это должно сохранить верно?

в консоли я вижу

===========================================
le modified text (body attr) here

Я вставляю span в текст, и в консоли (выше) это показывает, что изменения успешныв заявлении пут.Но когда я перерисовываю страницу, все возвращается на круги своя (элемент inspect не показывает интервалов)

Одна вещь, которую я нахожу странной, состоит в том, что оператор put выполняется до

"Processing NameOfController#action (for ....)" 

со всеми вызовами БД и тому подобное.Я прокручиваю вниз до того места, где будет Content.find (он там дважды, так что это легко), и я вижу это:

SHOW FIELDS FROM `contents`
  Content Load (1.6ms)   SELECT * FROM `contents` WHERE (`contents`.`id` = 328) 
  SQL (0.2ms)   BEGIN
  SQL (0.1ms)   COMMIT
  SQL (0.1ms)   BEGIN
  SQL (0.2ms)   COMMIT
  CACHE (0.0ms)   SELECT * FROM `contents` WHERE (`contents`.`id` = 328) 
  SQL (0.1ms)   BEGIN
  SQL (0.1ms)   COMMIT

Теперь он говорит, что загружает второй вызов из кэша ... чтос этим?так как я изменил его с момента последнего .find ()?

Я использую Ruby on Rails 2.3.8

ОБНОВЛЕНИЕ: включение предложений Дэна Сивера:

  content = Content.uncached_find(params[:content_id])
  content.body = content.body.insert(start_index, span_open)
  content.save!
  content.body = content.body.insert(end_index + span_open.length, span_close)
  content.save!
  a = content.body
# ActiveRecord::Base.connection.update("
#      UPDATE `contents`
#      SET body = '#{content.body}'
#      WHERE id = #{params[:content_id]}")
puts "=========================================="
content = Content.uncached_find(params[:content_id])
  puts (a == content.body).inspect

выход / терминал:

==========================================
false

Content Load (1.5ms)   SELECT * FROM `contents` WHERE (`contents`.`id` = 351) 
  SQL (0.1ms)   BEGIN
  SQL (0.1ms)   COMMIT
  SQL (0.1ms)   BEGIN
  SQL (0.2ms)   COMMIT
  Content Load (0.3ms)   SELECT * FROM `contents` WHERE (`contents`.`id` = 351) 

Ответы [ 2 ]

4 голосов
/ 08 ноября 2011

Способ работы кэширования SQL Rails заключается в том, что запросы кэшируются внутри действия:

Однако важно отметить, что кэши запросов создаются в начале действия и уничтожаются в конце этого действия и, таким образом, сохраняются только на время действия. Если вы хотите хранить результаты запросов более настойчиво, вы можете использовать Rails, используя низкоуровневое кэширование.

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

Обновление Если ранее не использовался некэшированный, кажется, что он определен в активной записи, поэтому вам придется добавить метод класса к содержимому, как показано ниже:

def self.uncached_find(content_id)
  uncached do 
    find(content_id)
  end 
end

Затем используйте Content.uncached_find(params[:content_id]) ( документация ), где вы будете использовать Content.find

Обновление 2 Я вижу проблему сейчас !! Вы на самом деле ничего не модифицируете. String#insert возвращает измененную строку, она не меняет content.body на месте, вам необходимо сделать следующее:

content.body = content.body.insert(start_index, span_open)

Попробуйте приведенную выше строку с сохранением, и оно должно работать

0 голосов
/ 09 ноября 2011

для принудительного обновления:

ActiveRecord::Base.connection.update("
  UPDATE `contents`
  SET body = '#{content.body}'
  WHERE id = #{params[:content_id]}")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...