{"id":15715827,"url":"https://github.com/gnapse/redis-attrs","last_synced_at":"2025-05-12T23:53:33.114Z","repository":{"id":7115807,"uuid":"8409699","full_name":"gnapse/redis-attrs","owner":"gnapse","description":"A module that allows Ruby objects to define attributes backed by a Redis data store. Works with any class or ORM.","archived":false,"fork":false,"pushed_at":"2013-08-27T14:54:28.000Z","size":271,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"develop","last_synced_at":"2025-05-12T23:53:27.288Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gnapse.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-02-25T13:34:33.000Z","updated_at":"2016-06-23T02:07:51.000Z","dependencies_parsed_at":"2022-07-31T14:49:05.355Z","dependency_job_id":null,"html_url":"https://github.com/gnapse/redis-attrs","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gnapse%2Fredis-attrs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gnapse%2Fredis-attrs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gnapse%2Fredis-attrs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gnapse%2Fredis-attrs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gnapse","download_url":"https://codeload.github.com/gnapse/redis-attrs/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253843185,"owners_count":21972870,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-03T21:43:10.851Z","updated_at":"2025-05-12T23:53:33.096Z","avatar_url":"https://github.com/gnapse.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Redis::Attrs - Add attributes to Ruby classes backed by Redis\n\n[![Code Climate](https://codeclimate.com/github/gnapse/redis-attrs.png)](https://codeclimate.com/github/gnapse/redis-attrs)\n\nThis gem is an amalgamation of the ideas found within the [redis_props][redis_props]\nand [redis-objects][redis-objects] gems, plus a few new ideas here and there.  It\nprovides a way to define, on any Ruby class, some attributes that are backed by\n[Redis][redis] behind the curtain.\n\nHere are some of the characteristics that define this library:\n\n- Easy to integrate directly with existing ORMs - ActiveRecord, DataMapper, etc.\n- Not confined to ORMs. Use it in whatever Ruby classes you want.\n- It does work better with ORMs because it requires each object to provide a\n  unique id identifying it, something already provided by most ORMs out of the box.\n- Supports scalar value types, as well as more complex value types such as\n  collection types, counters and locks.\n- Integers are returned as integers, rather than '17'. The same holds for dates,\n  times, floats, etc.\n- Collection types can be assigned a Ruby-style collection to set their whole\n  content at once, resetting whatever content there was in the Redis key.\n- The user can add support for more scalar data types with no built-in support.\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n    gem 'redis-attrs'\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install redis-attrs\n\n## Setting up the connection\n\nYou can include some of the following code snippets at the beginning of your\napp or script.  In case you're using Rails, you can use an initializer.\n\n```ruby\n# Standard connection\nRedis::Attrs.redis = Redis.new\n\n# Connection with specific parameters\nRedis::Attrs.redis = Redis.new(host: 'hostname', port: 8888, password: 'secret')\n\n# You can even use a redis namespace\nRedis::Attrs.redis = Redis::Namespace.new(\"blah\", redis: Redis.new)\n```\n\n## Usage\n\nStart by defining some attributes on your class:\n\n```ruby\nclass Film\n  include Redis::Attrs\n  redis_attrs :title =\u003e :string, :length =\u003e :integer\n  redis_attrs :released_on =\u003e :date, :cast =\u003e :list\n\n  # Remember that the objects need an id for this to work\n  attr_reader :id\n  def initialize(id)\n    @id = id\n  end\n\n  def presentation_title\n    \"#{title} (#{released_on.year})\"\n  end\nend\n```\n\nThen you can use those attributes as you would regularly, but internally they are\nreading from and writing to Redis.\n\n```ruby\n\u003e\u003e film = Film.new(3)\n\u003e\u003e film.title = \"Argo\"\n\u003e\u003e film.released_on = \"2012-10-12\"\n\u003e\u003e puts film.presentation_title\nArgo (2012)\n\u003e\u003e puts film.cast.size\n0\n\u003e\u003e film.cast = [\"Ben Affleck\", \"Alan Arkin\", \"Brian Cranston\"]\n\u003e\u003e puts film.cast.size\n3\n\u003e\u003e puts film.cast[-3]\nBen Affleck\n```\n\n`Redis::Attrs` will work on _any_ class that provides an `id` method that returns\na unique value.  `Redis::Attrs` will automatically create keys that are unique to\neach object, in the format `class_name:id:attr_name`.\n\n### Supported types\n\n`Redis::Attrs` supports the following scalar types: `string`, `integer`, `float`,\n`boolean`, `date` and `time`. These are automatically serialized and deserialized\nwhen written to and read from Redis.\n\nIn addition, the library also supports some collection types and a couple other\nnon-scalar types: `list`, `hash`, `set`, `sorted_set`, `counter` and `lock`.  These\nare all implemented using the [redis-objects][redis-objects] gem, each type handled\nby a class that encapsulate all Redis logic around them.\n\n### Defining new scalar types\n\nIn addition to the predefined scalar types listed above, the user can define its\nown scalar types, by subclassing `Redis::Attrs::Scalar` and defining how to serialize\nand deserialize its values.\n\nThe following example defines a data-type that stores its values serialized as JSON.\nThe `serialize` and `deserialize` methods define how this process is done.  After\nregistering the type with `Redis::Attrs`, a new attribute is added to the class\n`Film` defined above.\n\n```ruby\nclass JSONScalar \u003c Redis::Attrs::Scalar\n  def serialize(value)\n    value.to_json\n  end\n\n  def deserialize(value)\n    JSON.parse(value)\n  end\nend\n\nRedis::Attrs.register_type(:json, JSONScalar)\n\nclass Film\n  redis_attrs :director =\u003e :json\nend\n```\n\nAfter the definitions above, more complex data structures could be stored as a single\nscalar value, by being serialized as JSON.\n\n```ruby\n\u003e\u003e film = Film.new(1)\n\u003e\u003e film.director = { \"first_name\" =\u003e \"Ben\", \"last_name\" =\u003e \"Affleck\" }\n\u003e\u003e puts Redis::Attrs.redis.get(\"film:1:director\")\n{\"first_name\":\"Ben\",\"last_name\":\"Affleck\"}\n```\n\n### Attribute configuration options\n\nThe complex attribute types support some configuration options, mostly specific to\neach type.  When an attribute needs to be configured with some of these options, then\nit must be declared with the singular version of the method `redis_attrs`, like below:\n\n```ruby\nredis_attr :crawl, :lock, :expiration =\u003e 15.minutes\nredis_attr :cast, :list, :marshal =\u003e true\n```\n\nFor more details about the supported configuration options for each of the complex\ndata types, please refer to the [redis-objects][redis-objects] gem.\n\n### Filtering collection values\n\nThere's an attribute configuration option for lists and sets, the `:filter` option,\nthat allows the user to define a function that will modify the items upon insertion\ninto the collection.\n\n```ruby\nclass Film\n  redis_attr :genres, :set, :filter =\u003e lambda { |v| v.strip.downcase.gsub(/\\s+/, ' ') }\nend\n```\n\nAfter the above declaration we could do:\n\n```ruby\n\u003e\u003e film = Film.new(1)\n\u003e\u003e film.genres = [\"Action \", \"  drama\", \"film   Noir\", \"Drama\", \"Film noir \"]\n\u003e\u003e puts film.genres.members.sort\n[\"action\", \"drama\", \"film noir\"]\n```\n\n## Contributing\n\n1. Fork it\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create new Pull Request\n\n[redis]: http://redis.io\n[redis_props]: http://github.com/obie/redis_props\n[redis-objects]: http://github.com/nateware/redis-objects\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgnapse%2Fredis-attrs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgnapse%2Fredis-attrs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgnapse%2Fredis-attrs/lists"}