Achaius
Achaius

Reputation: 6124

How to use block to get the object?

I am using cache in my application and have used a common method to fetch the key.

def cache_key(key, options = {}, &block)
  unless block.call.nil?
    Rails.cache.fetch(key, expires_in: 30.minutes, &block)
  else
    return nil
  end
end

In the above example, I am trying to get the result of the block. If it is nil,I don't want to fetch the key and I return nil. In this case block is called twice so if i run this method, it generates two queries.

How can I simplify this better?

Upvotes: 0

Views: 183

Answers (2)

Chris Heald
Chris Heald

Reputation: 62668

What you really want is this:

def cache_key(key, options = {}, &block)
  options = options.merge(expires_in: 30.minutes)
  unless value = Rails.cache.read(key, options)
    value = block.call
    Rails.cache.write(key, value, options) unless value.nil?
  end
  value
end

This'll first try to read the cache. If the value is (nil, false), it'll execute the block. If the result of the block is non-nil, it'll write it to the cache. The value (either the cached value or the block result, as appropriate) is then returned.

Upvotes: 1

Mori
Mori

Reputation: 27789

def cache_key(key, options = {}, &block)
  value = block.call
  return nil if value.nil?
  Rails.cache.fetch(key, expires_in: 30.minutes) { value }

Upvotes: 1

Related Questions