<commit_before># Cachable
Caching is often a bother. This gem allows you to simply wrap your code in a block and have it be cached with redis.

## Installation
Add this line to your application's Gemfile:

```ruby
gem 'cachable'
```

You must also add redis to your app. On heroku, you can add [Heroku Redis](https://elements.heroku.com/addons/heroku-redis).

## Usage
At its hearty, this gem is the `unless_cached` method. 
Although no options are required, it accepts the following:
 - key. If present, will be added to the base key to generate the full key. Defaults to the name of the caller.
 - json. If true, will serialize and deserialize the result as json
 - expiration Time for which to cache the result. Defaults to 1 day
 - json_options. Options that get passed into json serialization and deserialization
 - skip_cache. If true, will not populate the cache -- this can be used if you populate the cache elsewhere, but still want to check if there's something there. 

### Examples
In your model:

```ruby
include Cachable

def your_method
  unless_cached do 
    # ... output of this will be cached under the key model_name_id_updated_at_your_method 
  end
end
```

Of course, `unless_cached` accepts a variety of options:
```ruby
# opts[:key]. If present, will be added to the base key to generate the full key. Defaults to the name of the caller.
unless_cached(key: 'some_key') do
  # will be stored under the key model_name_id_some_key
end


# opts[:json]. If true, will serialize and deserialize the result as json
unless_cached(json: true) do
  {
    json: 'object'
  }
end

# opts[:expiration]. Time for which to cache the result. Defaults to 1 day
unless_cached(expiration: 30.minutes) do
  # result will expire in half an hour
end


# opts[:json_options]. Options that get passed into json serialization and deserialization
unless_cached(json: true, json_options: {allow_nan: true}) do
  {
    value: Float::NAN
  }
end
```

## Other features

### Deleting from the cache
Sometimes you want to delete something from the cache. 
This can be done using the `delete_from_cache` method, which takes in one or more keys. 
These keys are either the 
```ruby
delete_from_cache(:key1, :key2)
```

A special use case is after the changes have been committed. 
For this, you can use the special `purge_cache` callback. 
You must define the `tracked_cache_keys` method for this to work properly. 
The following example will clear the cache for `cached_a` and `cached_b`, but not `cached_c`.
```ruby
# in your model
after_commit :purge_cache

def tracked_cache_keys
  [:cached_a, :cached_b]
end

def cached_a
  unless_cached do 
    # ...
  end
end

def cached_b
  unless_cached do <commit_msg>Documented configuration<commit_after># Cachable
Caching is often a bother. This gem allows you to simply wrap your code in a block and have it be cached with redis.

## Installation
Add this line to your application's Gemfile:

```ruby
gem 'cachable'
```

You must also add redis to your app. On heroku, you can add [Heroku Redis](https://elements.heroku.com/addons/heroku-redis).

## Usage
At its hearty, this gem is the `unless_cached` method. 
Although no options are required, it accepts the following:
 - key. If present, will be added to the base key to generate the full key. Defaults to the name of the caller.
 - json. If true, will serialize and deserialize the result as json
 - expiration Time for which to cache the result. Defaults to 1 day
 - json_options. Options that get passed into json serialization and deserialization
 - skip_cache. If true, will not populate the cache -- this can be used if you populate the cache elsewhere, but still want to check if there's something there. 

### Examples
In your model:

```ruby
include Cachable

def your_method
  unless_cached do 
    # ... output of this will be cached under the key model_name_id_updated_at_your_method 
  end
end
```

Of course, `unless_cached` accepts a variety of options:
```ruby
# opts[:key]. If present, will be added to the base key to generate the full key. Defaults to the name of the caller.
unless_cached(key: 'some_key') do
  # will be stored under the key model_name_id_some_key
end


# opts[:json]. If true, will serialize and deserialize the result as json
unless_cached(json: true) do
  {
    json: 'object'
  }
end

# opts[:expiration]. Time for which to cache the result. Defaults to 1 day
unless_cached(expiration: 30.minutes) do
  # result will expire in half an hour
end


# opts[:json_options]. Options that get passed into json serialization and deserialization
unless_cached(json: true, json_options: {allow_nan: true}) do
  {
    value: Float::NAN
  }
end
```

## Other features

### Configuring the redis connection
It defaults to checking the `REDIS_URL` and the `HEROKU_REDIS_URL` environment variables to make a connection to redis. 
However, you may wish to change the way you connect to redis. Create an initializer in `config/initializers/cachable.rb`. 
```ruby
Cachable::configure do |config|
  
  # set a lambda to get a redis connection
  config.redis_connection = -> {
    Redis.new
  }
  
  # set the redis instance directly
  config.redis_instance = Redis.new
  
  # or set the redis url
  config.redis_url = 'YOUR REDIS URL'
  
end
```

### Deleting from the cache
Sometimes you want to delete something from the cache. 
This can be done using the `delete_from_cache` method, which takes in one or more keys. 
These keys are either the 
```ruby
delete_from_cache(:key1, :key2)
```

A special use case is after the changes have been committed. 
For this, you can use the special `purge_cache` callback. 
You must define the `tracked_cache_keys` method for this to work properly. 
The following example will clear the cache for `cached_a` and `cached_b`, but not `cached_c`.
```ruby
# in your model
after_commit :purge_cache

def tracked_cache_keys
  [:cached_a, :cached_b]
end

def cached_a
  unless_cached do 
    # ...
  end
end

def cached_b
  unless_cached do 
{'fraction_non_alphanumeric': 0.0716432865731463, 'fraction_numerical': 0.002004008016032064, 'mean_word_length': 4.020117351215423, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 4, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2575109', 'n_tokens_mistral': 1857, 'n_tokens_neox': 1765, 'n_words': 832}