{"id":14956047,"url":"https://github.com/hugomarquez/spreeference","last_synced_at":"2026-02-09T15:05:14.984Z","repository":{"id":59156082,"uuid":"82503060","full_name":"hugomarquez/spreeference","owner":"hugomarquez","description":"Application-wide and per model cached and persisted preferences","archived":false,"fork":false,"pushed_at":"2018-12-03T20:58:15.000Z","size":34,"stargazers_count":0,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-14T09:46:36.484Z","etag":null,"topics":["cache","configuration","configuration-management","preferences","rails","rails-engine","ruby","rubyonrails","spree"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hugomarquez.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-02-20T01:17:00.000Z","updated_at":"2018-12-03T20:58:17.000Z","dependencies_parsed_at":"2022-09-13T20:11:28.103Z","dependency_job_id":null,"html_url":"https://github.com/hugomarquez/spreeference","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hugomarquez%2Fspreeference","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hugomarquez%2Fspreeference/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hugomarquez%2Fspreeference/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hugomarquez%2Fspreeference/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hugomarquez","download_url":"https://codeload.github.com/hugomarquez/spreeference/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247642568,"owners_count":20971922,"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":["cache","configuration","configuration-management","preferences","rails","rails-engine","ruby","rubyonrails","spree"],"created_at":"2024-09-24T13:12:14.062Z","updated_at":"2026-02-09T15:05:09.961Z","avatar_url":"https://github.com/hugomarquez.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Spree + Preference = Spreeference\n\n[![Gem Version](https://badge.fury.io/rb/spreeference.svg)](https://badge.fury.io/rb/spreeference)\n[![Build Status](https://travis-ci.org/hugomarquez/spreeference.svg?branch=master)](https://travis-ci.org/hugomarquez/spreeference)\n[![Coverage Status](https://coveralls.io/repos/github/hugomarquez/spreeference/badge.svg?branch=master)](https://coveralls.io/github/hugomarquez/spreeference?branch=master)\n\n## Overview\nThe reason for this gem is to extract from Spree Core the Preferences functionality, which can be used in other projects besides Spree and e-commerce.\n\nCopyright (c) 2009-2015 [Spree Commerce][1] and [Contributors][2], released under the [New BSD License][3]\n\n[1]: https://github.com/spree\n[2]: https://github.com/hugomarquez/spreeference/graphs/contributors\n[3]: https://github.com/hugomarquez/spreeference/blob/master/LICENSE.md\n\nSpreeference preferences support general application configuration and preferences per model instance. Additional preferences can be added by your application or included extensions.\n\nTo implement preferences for a model, simply add a new column called `preferences`. This is an example migration:\n\n```ruby\nclass AddPreferencesColumnToProducts \u003c ActiveRecord::Migration[4.2]\n  def up\n    add_column :products, :preferences, :text\n  end\n\n  def down\n    remove_column :products, :preferences\n  end\nend\n```\nThis will work if your model is a subclass of `Spreeference::ApplicationRecord`. If found, the `preferences`attribute gets serialized into a `Hash` and merged with the default values.\n\nAs another example, you might want to add preferences for users to manage their notification settings. Just make sure your `User` model inherits from `Spreeference::ApplicationRecord` then add the `preferences` column. You'll then be able to define preferences for `User`s without adding extra columns to the database table.\n\n## Installing into a new Rails application\nTo get up and running with spreeference in a new Rails application is simple. Just follow the instructions below.\n\t\t\n\t\trails new my_project\n\t\tcd my_project\n\t\techo \"gem 'spreeference'\" \u003e\u003e Gemfile\n\t\tbundle\n\t\trails g spreeference:install\n\t\trake db:migrate\n\n### Motivation\n\nPreferences for models within an application are very common. Although the rule of thumb is to keep the number of preferences available to a minimum, sometimes it's necessary if you want users to have optional preferences like disabling e-mail notifications.\n\nBoth use cases are handled by Spreeferences. They are easy to define, provide quick cached reads, persist across restarts and do not require additional columns to be added to your models' tables.\n\n## General Settings\n\nSpreeference comes with many application-wide preferences. They are defined in `app/models/spreeference/app_configuration.rb` and made available to your code through `Spreeference::Config`, e.g., `Spreeference::Config.site_name`.\n\nYou can add additional preferences under the `spreeference/app_configuration` namespace or create your own subclass of `Spreeference::Configuration`.\n\n```ruby\n# These will be saved with key: spreeference/app_configuration/hot_salsa\nSpreeference::AppConfiguration.class_eval do\n  preference :hot_salsa, :boolean\n  preference :dark_chocolate, :boolean, default: true\n  preference :color, :string\n  preference :favorite_number\n  preference :language, :string, default: 'English'\nend\n\n# Spreeference::Config is an instance of Spreeference::AppConfiguration\nSpreeference::Config.hot_salsa = false\n\n# Create your own class\n# These will be saved with key: kona/store_configuration/hot_coffee\nKona::StoreConfiguration \u003c Spreeference::Configuration\n  preference :hot_coffee, :boolean\n  preference :color, :string, default: 'black'\nend\n\nKONA::STORE_CONFIG = Kona::StoreConfiguration.new\nputs KONA::STORE_CONFIG.hot_coffee\n```\n\n## Defining Preferences\n\nYou can define preferences for a model within the model itself:\n\n```ruby\nclass User \u003c Spreeference::ApplicationRecord\n  preference :hot_salsa, :boolean\n  preference :dark_chocolate, :boolean, default: true\n  preference :color, :string\n  preference :favorite_number, :integer\n  preference :language, :string, default: \"English\"\nend\n```\nIn the above model, five preferences have been defined:\n\n* `hot_salsa`\n* `dark_chocolate`\n* `color`\n* `favorite_number`\n* `language`\n\nFor each preference, a data type is provided. The types available are:\n\n* `boolean`\n* `string`\n* `password`\n* `integer`\n* `text`\n* `array`\n* `hash`\n\nAn optional default value may be defined which will be used unless a value has been set for that specific instance.\n\n## Accessing Preferences\n\nOnce preferences have been defined for a model, they can be accessed either using the shortcut methods that are generated for each preference or the generic methods that are not specific to a particular preference.\n\n### Shortcut Methods\n\nThere are several shortcut methods that are generated. They are shown below.\n\nQuery methods:\n\n```ruby\nuser.prefers_hot_salsa? # =\u003e false\nuser.prefers_dark_chocolate? # =\u003e false\n```\n\nReader methods:\n\n```ruby\nuser.preferred_color      # =\u003e nil\nuser.preferred_language   # =\u003e \"English\"\n```\n\nWriter methods:\n\n```ruby\nuser.prefers_hot_salsa = false         # =\u003e false\nuser.preferred_language = \"English\"    # =\u003e \"English\"\n```\n\nCheck if a preference is available:\n\n```ruby\nuser.has_preference? :hot_salsa\n```\n\n### Generic Methods\n\nEach shortcut method is essentially a wrapper for the various generic methods shown below:\n\nQuery method:\n\n```ruby\nuser.prefers?(:hot_salsa)       # =\u003e false\nuser.prefers?(:dark_chocolate)  # =\u003e false\n```\n\nReader methods:\n\n```ruby\nuser.preferred(:color)      # =\u003e nil\nuser.preferred(:language)   # =\u003e \"English\"\n```\n\n```ruby\nuser.get_preference :color\nuser.get_preference :language\n```\n\nWriter method:\n\n```ruby\nuser.set_preference(:hot_salsa, false)     # =\u003e false\nuser.set_preference(:language, \"English\")  # =\u003e \"English\"\n```\n### Accessing All Preferences\n\nYou can get a hash of all stored preferences by accessing the `preferences` helper:\n\n```ruby\nuser.preferences # =\u003e {\"language\"=\u003e\"English\", \"color\"=\u003enil}\n```\n\nThis hash will contain the value for every preference that has been defined for the model instance, whether the value is the default or one that has been previously stored.\n\n### Default and Type\n\nYou can access the default value for a preference:\n\n```ruby\nuser.preferred_color_default # =\u003e 'blue'\n```\n\nTypes are used to generate forms or display the preference. You can also get the type defined for a preference:\n\n```ruby\nuser.preferred_color_type # =\u003e :string\n```\n### Configuration Through an Initializer\n\nDuring the Spreeference installation process, an initializer file is created within your application's source code. The initializer is found under `config/initializers/spreeference.rb`:\n\n```ruby\nSpreeference.config do |config|\n  # Example:\n  # Uncomment to override the default site name.\n  # config.site_name = \"Spree Demo Site\"\nend\n```\nThe `Spreeference.config` block acts as a shortcut to setting `Spreeference::Config` multiple times. If you have multiple default preferences you would like to override within your code you may override them here. Using the initializer for setting the defaults is a nice shortcut, and helps keep your preferences organized in a standard location.\n\n## Site-Wide Preferences\n\nYou can define preferences that are site-wide and don't apply to a specific instance of a model by creating a configuration file that inherits from `Spreeference::Configuration`.\n\n```ruby\nclass MyApplicationConfiguration \u003c Spreeference::Configuration\n  preference :theme, :string, default: \"Default\"\n  preference :show_splash_page, :boolean\n  preference :number_of_articles, :integer\nend\n```\n\nIn the above configuration file, three preferences have been defined:\n\n* theme\n* show_splash_page\n* number_of_articles\n\n### Configuring Site-Wide Preferences\n\nThe recommended way to configure site-wide preferences is through an initializer. Let's take a look at configuring the preferences defined in the previous configuration example.\n\n```ruby\nmodule Spree\n  MyApp::Config = MyApplicationConfiguration.new\nend\n\nMyApp::Config[:theme] = \"blue_theme\"\nMyApp::Config[:show_spash_page] = true\nMyApp::Config[:number_of_articles] = 5\n```\n\nThe `MyApp` name used here is an example and should be replaced with your actual application's name, found in `config/application.rb`.\n\nThe above example will configure the preferences we defined earlier. Take note of the second line. In order to set and get preferences using `MyApp::Config`, we must first instantiate the configuration object.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhugomarquez%2Fspreeference","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhugomarquez%2Fspreeference","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhugomarquez%2Fspreeference/lists"}