{"id":16239762,"url":"https://github.com/jalkoby/active_store_accessor","last_synced_at":"2025-03-19T16:31:36.067Z","repository":{"id":17560995,"uuid":"20364319","full_name":"jalkoby/active_store_accessor","owner":"jalkoby","description":"Get more from ActiveRecord::Store","archived":false,"fork":false,"pushed_at":"2017-07-07T00:03:52.000Z","size":266,"stargazers_count":17,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-28T19:53:16.479Z","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/jalkoby.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":"2014-05-31T20:15:54.000Z","updated_at":"2017-06-21T18:23:59.000Z","dependencies_parsed_at":"2022-09-11T02:23:02.913Z","dependency_job_id":null,"html_url":"https://github.com/jalkoby/active_store_accessor","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jalkoby%2Factive_store_accessor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jalkoby%2Factive_store_accessor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jalkoby%2Factive_store_accessor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jalkoby%2Factive_store_accessor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jalkoby","download_url":"https://codeload.github.com/jalkoby/active_store_accessor/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244006260,"owners_count":20382441,"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-10T13:45:05.280Z","updated_at":"2025-03-19T16:31:35.756Z","avatar_url":"https://github.com/jalkoby.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ActiveStoreAccessor\n\n[![Build Status](https://travis-ci.org/jalkoby/active_store_accessor.svg?branch=master)](https://travis-ci.org/jalkoby/active_store_accessor)\n[![Gem Version](https://badge.fury.io/rb/active_store_accessor.svg)](http://badge.fury.io/rb/active_store_accessor)\n[![Code Climate](https://codeclimate.com/github/jalkoby/active_store_accessor.png)](https://codeclimate.com/github/jalkoby/active_store_accessor)\n\n`active_store_accessor` makes a work with store accessors more productive. There is no need to cast a serialized attribute to a required type(boolean, time, float, etc). Just define it with a tiny wrapper method and everything is done for you.\n\n## Usage\n\nThe basic usage:\n\n```ruby\nclass Profile \u003c ActiveRecord::Base\n  active_store_accessor :info, age: :integer, birthday: :time\n\n  # with default values\n  active_store_accessor :info, score: { type: :float, default: 0.0 },\n    active: { type: :boolean, default: true }\nend\n\nprofile = Profile.new\nprofile.age = \"23\"\nprofile.age # =\u003e 23\nprofile.birthday = Time.new(2014, 5, 31)\nprofile.birthday # =\u003e 2014-05-31 00:00:00\nprofile.score # =\u003e 0.0\nprofile.score = 4.5\nprofile.score # =\u003e 4.5\n```\n\nThe extra logic in a property methods:\n```ruby\n# Story:\n#  users have a rank, but if a user was locked by admins\n#  nobody can change a rank \u0026 it's value should be equal to zero\nclass User\n  active_store_accessor :info, rank: :float\n\n  def rank\n    0 if locked?\n    super\n  end\n\n  def rank=(value)\n    super unless locked?\n  end\nend\n```\n\n## Adding a custom type\nAdd a custom type is easy enough:\n\n```ruby\n# using a block\nActiveStoreAccessor.add_type(:even) do |builder|\n  builder.to_source { |value| (value.to_i / 2) * 2 }\nend\n\n# using a lambda\nActiveStoreAccessor.add_type(:even) do |builder|\n  to_source = lambda { |value| (value.to_i / 2) * 2 }\n  builder.to_source(to_source)\nend\n\n# using a object with #call method\nclass EvenConvert\n  def call(value)\n    (value.to_i / 2) * 2\n  end\nend\n\nActiveStoreAccessor.add_type(:even) do |builder|\n  builder.to_source(EvenConvert.new)\nend\n```\n\nSometimes you need to deserialize your value of a custom type. To do it look at the following example:\n\n```ruby\nActiveStoreAccessor.add_type(:point) do |builder|\n  builder.to_source do |value|\n    \"#{ value.x },#{ value.y }\"\n  end\n\n  builder.from_source do |value|\n    parts = value.split(',')\n    Point.new(parts[0], parts[1])\n  end\nend\n```\n\nThere is a common issue when you use `block`-style to define a custom type:\n\n```ruby\nActiveStoreAccessor.add_type(:point) |builder|\n  builder.to_source do |value|\n    return unless value.is_a?(Point)\n    # ...\n  end\nend\n```\n\nRuby will rise an error Unexpected Return (LocalJumpError). To avoid it replace a block by a lambda:\n\n```ruby\nActiveStoreAccessor.add_type(:point) |builder|\n  to_source = lambda do |value|\n    return unless value.is_a?(Point)\n    # ...\n  end\n\n  builder.to_source(to_source)\nend\n```\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n    gem 'active_store_accessor'\n\nAnd then execute:\n\n    $ bundle\n\n## Requirements \u0026 dependencies\n\nThis library has been tested on ruby 1.9.3+ and activerecord 4.0+.\n\n## Contributing\n\n1. Fork it ( https://github.com/jalkoby/active_store_accessor/fork )\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 a new Pull Request\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjalkoby%2Factive_store_accessor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjalkoby%2Factive_store_accessor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjalkoby%2Factive_store_accessor/lists"}