Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ouyangjinting/ar_cache
A modern caching library for ActiveRecord inspired by cache-money and second_level_cache.
https://github.com/ouyangjinting/ar_cache
activerecord cache rails
Last synced: 3 months ago
JSON representation
A modern caching library for ActiveRecord inspired by cache-money and second_level_cache.
- Host: GitHub
- URL: https://github.com/ouyangjinting/ar_cache
- Owner: OuYangJinTing
- License: mit
- Created: 2020-11-30T10:45:12.000Z (about 4 years ago)
- Default Branch: main
- Last Pushed: 2024-08-22T17:49:18.000Z (5 months ago)
- Last Synced: 2024-10-11T03:42:13.059Z (3 months ago)
- Topics: activerecord, cache, rails
- Language: Ruby
- Homepage:
- Size: 217 KB
- Stars: 15
- Watchers: 3
- Forks: 1
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.txt
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# ArCache (This is outdated, please see [中文文档](README.zh-CN.md))
![Test Status](https://github.com/OuYangJinTing/ar_cache/workflows/CI/badge.svg)
[![Gem Version](https://badge.fury.io/rb/ar_cache.svg)](https://badge.fury.io/rb/ar_cache)`ArCache` is an modern cacheing library for `ActiveRecord` inspired by cache-money and second_level_cache.
It works automatically by overridden `ActiveRecord` related CURD code.
When executing standard `ActiveRecord` query, it will first query the cache, and if there is none in the cache,
then query the database and write the result to the cache.> **! WARNING: Please read these [information](#Warning) before using `ArCache`.**
## Features
- `Low impact`: If your code strictly comply with the activerecord style, you don’t need to modify any code.([see more details](#Warning))
- `Read cache`: Automatically intercept ActiveRecord queries, then try to fetch data from cache.
- `Write cache`: If the query is cacheable and the cached data is not exists, it will be automatically written to the cache after the query.
- `Expire cache`: Automatically expire cache after updated/modified data.
- `Iterative cache`: The cache version will be updated after table fields or `ArCache` switch changed.
- `Shared cache`: The cache is not only used with ActiveRecord, you can easily use it in other places.([see examples](examples))## Installation
Add this line to your application's Gemfile:
```ruby
gem 'ar_cache'
```And then execute:
```shell
bundle install
```## Post Installation
If is an `rails` application:
```shell
rails generate ar_cache:install
```Otherwise copy [configuration](lib/generators/ar_cache/templates/configuration.rb) and [migration](lib/generators/ar_cache/templates/migrate/create_ar_cache_records.rb.tt) files to your application.
After that review the migrations then migrate:
```shell
rake db:migrate
```## Usage
`ArCache` works automatically, so you don’t need to care about how to use the cache, just need to know how to skip and delete the cache.
Skip cache:
- `ArCache#skip_cache`, eg:
```ruby
# All queries in the block will not use the cache.
ArCache.skip_cache { User.find(1) }
```- `ActiveRecord::Persistence#reload`, eg:
```ruby
User.find(1).reload
```- `ActiveRecord::Relation#reload`, eg:
```ruby
# When reload is called after the associated target has been loaded, the cache will be skipped.
User.where(id: 1).load.reload
```- `ActiveRecord::Associations::Association#reload`, eg:
```ruby
# When reload is called after the associated target has been loaded, the cache will be skipped.
user.association(:account).load_target.reload
```Delete cache:
- `ArCache::Table`, eg:
```ruby
User.ar_cache_table.delete(id...)
User.first.ar_cache_table.delete(id...)
```## Configuration
For configuration information, please see [configuration](lib/generators/ar_cache/templates/configuration.rb) file.
## Cacheable query
If all the following conditions are met, ArCache will try to read the cache:
- **Use hash as `#where` parameter**.
- Query condition contains unique index.
- Condition of unique index is only one array or no array.
- No call `#select` or select value is table column.
- No call `#order` or order value is table column and only one.
- No call `#limit` or value of the unique index isn't array.
- No call `#joins`, `#left_joins`, `#skip_query_cache!`, `#explain`, `#from`, `#group`, `#offset`, `#lock`
- ...**Cacheable example:**
```ruby
User.find(1) # support primary key cache
User.where(id: [1, 2]) # support multi-value unique index cache
User.where(email: '[email protected]') # support sigle-column unique index cache
User.where(name: 'foobar', status: :active) # support multi-column unique index cache
User.includes(:account).where(id: [1, 2]) # support association preload cache
User.first.account # support association reader cach
```The association cache support belongs_to and has_one, small amount of complex has_one(scope, through:, as:) don't support, then has_many cache support, please watch to future version.
## Cache iteration
The following cases will cause cache iteration:
- Table field changes.
- Turn on `ArCache` or turn off `ArCache`.
- Call `#upsert_all` method.**Notice: After iteration, all existing caches of the table will be expired!**
## How it works(Work in progress)
`ArCache` works based on the unique index of the table.
## Warning
- Prohibit the use of `#execute` update/delete operations!
- Prohibit use `ActiveRecord` other underlying methods to directly update/delete data! (You is a fake activerecord user if this code appears)
- Prohibit skip `ActiveRecord` directly update/delete data!If you have to do this, please consider turning off ArCache.
## Alternatives
There are some other gems implementations for `ActiveRecord` cache such as:
- [identity_cache](https://github.com/Shopify/identity_cache)
- [second_level_cache](https://github.com/hooopo/second_level_cache)
- [cache-money](https://github.com/ngmoco/cache-money)However, `ArCache` has some differences:
- It don’t depend with `ActiveRecord` callbacks, so don’t need to deal with dirty cache manually.
- It cache real database data, so can use it's cache at other places.
- It can automatically handle cache iteration, so don't need to update cache version manually.
- It proxy standard ActiveRecord query, so don't need to modify the code and remember the additional api.
- The new data need to perform a query before the cache will take effect.
- The cache will not be updated after the data is updated, but the cache will be expired directly.## Development
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
## Contributing
Bug reports and pull requests are welcome on GitHub at . This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/OuYangJinTing/ar_cache/blob/master/CODE_OF_CONDUCT.md).
## License
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
## Code of Conduct
Everyone interacting in the `ArCache` project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/OuYangJinTing/ar_cache/blob/master/CODE_OF_CONDUCT.md).