A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/palkan/store_attribute below:

palkan/store_attribute: ActiveRecord extension which adds typecasting to store accessors

ActiveRecord extension which adds typecasting to store accessors.

Originally extracted from not merged PR to Rails: rails/rails#18942.

In your Gemfile:

# for Rails 6.1+ (7 is supported)
gem "store_attribute", "~> 1.0"

# for Rails 5+ (6 is supported)
gem "store_attribute", "~> 0.8.0"

# for Rails 4.2
gem "store_attribute", "~> 0.4.0"

You can use store_attribute method to add additional accessors with a type to an existing store on a model.

store_attribute(store_name, name, type, options)

Where:

Type casting occurs every time you write data through accessor or update store itself and when object is loaded from database.

Note that if you update store explicitly then value isn't type casted.

Examples:

class MegaUser < User
  store_attribute :settings, :ratio, :integer, limit: 1
  store_attribute :settings, :login_at, :datetime
  store_attribute :settings, :active, :boolean
  store_attribute :settings, :color, :string, default: "red"
  store_attribute :settings, :colors, :json, default: ["red", "blue"]
  store_attribute :settings, :data, :datetime, default: -> { Time.now }
end

u = MegaUser.new(active: false, login_at: "2015-01-01 00:01", ratio: "63.4608")

u.login_at.is_a?(DateTime) # => true
u.login_at = DateTime.new(2015, 1, 1, 11, 0, 0)
u.ratio # => 63
u.active # => false
# Default value is set
u.color # => red
# Default array is set
u.colors # => ["red", "blue"]
# A dynamic default can also be provided
u.data # => Current time
# And we also have a predicate method
u.active? # => false
u.reload

# After loading record from db store contains casted data
u.settings["login_at"] == DateTime.new(2015, 1, 1, 11, 0, 0) # => true

# If you update store explicitly then the value returned
# by accessor isn't type casted
u.settings["ratio"] = "3.141592653"
u.ratio # => "3.141592653"

# On the other hand, writing through accessor set correct data within store
u.ratio = "3.141592653"
u.ratio # => 3
u.settings["ratio"] # => 3

You can also specify type using usual store_accessor method:

class SuperUser < User
  store_accessor :settings, :privileges, login_at: :datetime
end

Or through store:

class User < ActiveRecord::Base
  store :settings, accessors: [:color, :homepage, login_at: :datetime], coder: JSON
end

With store_attribute, you can provide default values for the store attribute. This functionality follows Rails behaviour for attribute ..., default: ... (and is backed by Attribute API).

You must remember two things when using defaults:

The examples below demonstrate these caveats:

# Database schema
create_table("users") do |t|
  t.string :name
  t.jsonb :extra
end

class RawUser < ActiveRecord::Base
  self.table_name = "users"
end

class User < ActiveRecord::Base
  attribute :name, :string, default: "Joe"
  store_attribute :extra, :expired_at, :date, default: -> { 2.days.from_now }
end

Date.current #=> 2022-03-17

user = User.new
user.name #=> "Joe"
user.expired_at #=> 2022-03-19
user.save!

raw_user = RawUser.find(user.id)
raw_user.name #=> "Joe"
raw_user.expired_at #=> 2022-03-19

another_raw_user = RawUser.create!
another_user = User.find(another_raw_user.id)

another_user.name #=> nil
another_user.expired_at #=> nil

By default, Store Attribute returns the default value even when the record is persisted but the attribute name is not present:

user = User.create!(extra: {})
user.expired_at #=> 2022-03-19

You can disable this behaviour by setting the store_attribute_unset_values_fallback_to_default class option to false in your model:

class User < ApplicationRecord
  self.store_attribute_unset_values_fallback_to_default = false
end

user = User.create!(extra: {})
user.expired_at #=> nil

You can also configure the global default for this option in an initializer or application configuration:

# config/initializers/store_attribute.rb
# # or
# config/application.rb
StoreAttribute.store_attribute_unset_values_fallback_to_default = false

Bug reports and pull requests are welcome on GitHub at https://github.com/palkan/store_attribute.

For local development, you'll need PostgreSQL up and running. You can either install it on your host machine or run via Docker as follows:

docker run --name store_attribute_postgres -e POSTGRES_HOST_AUTH_METHOD=trust -e POSTGRES_USER=$USER -e POSTGRES_PASSWORD=postgres -p 5432:5432 -d postgres
docker exec -it store_attribute_postgres createdb -U $USER store_attribute_test

The gem is available as open source under the terms of the MIT License.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4