views:

312

answers:

3

Is there a way to do this in Rails: I have an activerecord query

@posts = Post.find_by_id(10)

Anytime the query is called, SQL is generated and executed at the DB that looks like this

SELECT * FROM 'posts' WHERE id = 10

This happens every time the AR query is executed. Similarly with a helper method like this

<%= f.textarea :name => 'foo' %> 
#=> <input type='textarea' name='foo' />

I write some Railsy code that generates some text that is used by some other system (database, web browser). I'm wondering if there's a way to write an AR query or a helper method call that generates the text in the file. This way the text rendering is only done once (each time the code changes) instead of each time the method is called?

A: 

I'm not sure I understand your question fully.

If you're asking about the generated query, you can just do find_by_sql and write your own SQL if you don't want to use the active record dynamic methods.

If you're asking about caching the resulset to a file, it's already in the database, I don't know that if it was in a file it would be much more efficient.

JRL
not even cache the resultset, just cache the generated query. I know about find_by_sql. MY issue is that i dont want to write raw sql, i like activerecord. But it seems like a waste to generate the same string thousands of times.
I would think that whatever the waste, it would never be a problem. This is generated by the code. The bottleneck will most likely **always** be the database.
JRL
+1  A: 

Look at the line, it may be going to the database for the first one but ones after it could be saying CACHE at the start of the line meaning it's going to ActiveRecord's query cache.

It also sounds to me like you want to cache the page, not the query. And even if it were the query, I don't think it's as simple as find_by_id(10) :)

Ryan Bigg
A: 

Like Radar suggested you should probably look into Rails caching. You can start with something simple like the memory store or file cache and then move to something better like memcached if necessary. You can throw in some caching into the helper method which will cache the result after it is queried once. So for example you can do:

    id = 10 # id is probably coming in as a param/argument
    cache_key = "Post/#{id}"
    @post = Rails.cache.read(cache_key)
    if @post.nil?
      @post = Post.find_by_id(id)
      # Write back to the cache for the next time
      Rails.cache.write(cache_key,@post)
    end

The only other thing left to do is put in some code to expire the cache entry if the post changes. For that take a look at using "Sweepers" in Rails. Alternatively you can look at some of the caching gems like Cache-fu and Cached-model.

jkupferman