---
title: Model Preferences
description: Add typed configuration options to Spree models using model preferences, including supported types, default values, and reading or writing stored values.
---

Model preferences allow you to easily extend Spree models with configuration options. Thanks to this you can store useful information on Spree models, eg.

```ruby
store.preferred_timezone = 'Europe/Warsaw'
store.save
```

## Defining Model Preferences

To define a model preference, you need to add them to your model class.

Make sure to generate a migration to add the `preferences` column to the table. This column will store the preferences in a serialized format.

```bash
spree generate migration AddPreferencesToSpreeBrands preferences:text
```

Run the migration.

```bash
spree migrate
```

```ruby server/app/models/spree/brand.rb
module Spree
  class Brand < Spree.base_class
    preference :featured, :boolean, default: false
    preference :display_name, :string
  end
end
```

Any model inheriting from `Spree.base_class` can declare preferences — the reader and writer methods come with it, so there is nothing to include. The values live in that model's `preferences` column.

## Accessing Model Preferences

Once 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.

### Shortcut Methods

There are several shortcut methods that are generated. They are shown below.

Query methods:

```ruby
brand.prefers_featured? # => false
```

Reader methods:

```ruby
brand.preferred_featured      # => false
brand.preferred_display_name   # => "English"
```

Writer methods:

```ruby
brand.prefers_featured = false         # => false
brand.preferred_display_name = "English"    # => "English"
```

> **NOTE:** Remember to run `brand.save` after setting the preference value to save the changes to the database.

Check if a preference is available:

```ruby
brand.has_preference? :featured
```

### Generic Methods

When the preference name is only known at runtime, read and write it generically:

```ruby
brand.get_preference(:featured)             # => false
brand.set_preference(:display_name, 'Wilson')
```

### Accessing All Preferences

You can get a hash of all stored preferences by accessing the `preferences` helper:

```ruby
brand.preferences # => { 'featured' => false, 'display_name' => 'Wilson' }
```

This 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.

## Models with preferences

Around fifty models use preferences, and the pattern is always the same: a family of subclasses that share a table but need different settings.

| Family | What the preferences hold |
|---|---|
| `Spree::Calculator` | The numbers behind a delivery charge or a discount — flat rate, percentage, tiers |
| `Spree::PaymentMethod` | Gateway credentials and per-provider options |
| `Spree::Promotion::Rules` and `Spree::Promotion::Actions` | What a promotion matches on, and what it does |
| `Spree::Integration` | Per-service configuration and API keys |
| `Spree::PriceRules` and `Spree::DeliveryMethodRules` | When a price list or a delivery method applies |
| `Spree::Store`, `Spree::Channel` and `Spree::Market` | Merchant settings — timezone, units, currency behaviour |

This is why preferences exist rather than columns: `Spree::Calculator::FlatRate` and `Spree::Calculator::TieredPercent` are rows in one table with entirely different settings, and neither wants a column the other leaves null.
* `Spree::Theme`
