3
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

so the above is what I've been trying to do. lots of saves.. it should save right?

in the console I see

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

I'm inserting span's into text, and in the console (above) it shows the changes successful in the puts statement. But when I rerender the page, everything is back the way it was (inspect element shows no spans)

One thing that I find weird is that the puts statement executes before the

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

with all the DB calls and such. I scroll down to where Content.find would be (it's there twice, so this is easy) and I see this:

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

Now, it says that it's loading the second call from cache... what's up with that? since I've changed it since the last .find()?

I'm using Ruby on Rails 2.3.8

UPDATE: incorporating Dan Seaver's suggestions:

  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

output / terminal:

==========================================
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) 
NullVoxPopuli
  • 61,906
  • 73
  • 206
  • 352
  • have you tried content.reload? – jaydel Nov 03 '11 at 19:53
  • how would that help? I don't have issues getting the content. It's the saving part. =\ – NullVoxPopuli Nov 03 '11 at 20:03
  • how do you render the `body` ? if you do not mark it as `html_safe` or use `raw` it is escaped by default, so this could explain that your `` disappears. – m_x Nov 03 '11 at 20:15
  • I mean, the span not in the dom tree at all. When I say disappears, I mean it's not in content.body. =\ Notice how my DB calls don't ever call UPDATE `contents`? – NullVoxPopuli Nov 03 '11 at 20:24
  • I was wondering if doing the reload would avoid the caching issues. It would just be interesting information, not a real solution (which is why this is a comment, not an answer). I'd really love to know why it's using cache rather than a real select. – jaydel Nov 04 '11 at 11:26
  • Try printing content.body after you change it, to make sure the the content is actually changing – Dan McClain Nov 09 '11 at 17:30
  • It's changing. I actually have puts content.body in my code (after the second uncached_find). didn't want to add it here because it takes up a ton of space. it just... doesn't stay changed? idk. – NullVoxPopuli Nov 09 '11 at 17:32
  • like.. when I refresh the page. the changes made by .insert aren't kept. – NullVoxPopuli Nov 09 '11 at 17:38
  • @TheLindyHop: I feel like something is up with either your pre-save filters, or save itself. Have you added any filters, or overridden `save` – Dan McClain Nov 09 '11 at 18:04
  • I know I haven't overridden save, because it works in other controllers. as for filters, I use :only => :some_other_method, so it shouldn't affect this method. T_T – NullVoxPopuli Nov 09 '11 at 18:13

2 Answers2

4

The way that Rails SQL Caching works is that queries are cached within an action:

However, it’s important to note that query caches are created at the start of an action and destroyed at the end of that action and thus persist only for the duration of the action. If you’d like to store query results in a more persistent fashion, you can in Rails by using low level caching.

This article describes how you can avoid the cache with the following

Update Not having previously used uncached, it seems like is defined within active record, so you will have to add a class method to content like the following:

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

Then use Content.uncached_find(params[:content_id]) (documentation) where you would use Content.find

Update 2 I see the issue now!! You aren't actually modifying anything. String#insert returns a modified string, it does not modify content.body in place, you need to do the following:

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

Try the above line with your save, and it should work

Dan McClain
  • 11,780
  • 9
  • 47
  • 67
  • says uncached is undefined o.o. I'm using rails 2.3.8. Not sure if I mentioned that .=\ – NullVoxPopuli Nov 08 '11 at 14:33
  • @TheLindyHop: I have updated my answer, I suspect that `uncached` is part of ActiveRecord::Model – Dan McClain Nov 08 '11 at 15:47
  • while that solved my issue with the db not agreeing with .find was giving me. it doesn't solve the not-saving problem. In the mean time I do this: ActiveRecord::Base.connection.update("UPDATE `content` SET body = ....") ... so.. .not the ideal solution... but still a solution. – NullVoxPopuli Nov 09 '11 at 14:05
  • Using http://stackoverflow.com/questions/2328984/rails-extending-activerecordbase I was able to add uncached_find to all my activerecord models =D – NullVoxPopuli Nov 09 '11 at 16:38
  • I this this is a bug with .insert. I just did body = (completely different text) and the model saved o.o – NullVoxPopuli Nov 09 '11 at 22:09
0

to force updating:

ActiveRecord::Base.connection.update("
  UPDATE `contents`
  SET body = '#{content.body}'
  WHERE id = #{params[:content_id]}")
NullVoxPopuli
  • 61,906
  • 73
  • 206
  • 352