@spree/docs 0.1.292 → 0.1.293
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -14,12 +14,14 @@ store.save
|
|
|
14
14
|
|
|
15
15
|
To define a model preference, you need to add them to your model class.
|
|
16
16
|
|
|
17
|
-
Make sure to generate a migration to add the `preferences` column to the table. This column
|
|
17
|
+
Make sure to generate a migration to add the `preferences` column to the table. This column stores the preferences as JSON.
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
spree generate migration AddPreferencesToSpreeBrands preferences:
|
|
20
|
+
spree generate migration AddPreferencesToSpreeBrands preferences:jsonb
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
`jsonb` is for PostgreSQL, the default database. On MySQL or SQLite use `preferences:json`.
|
|
24
|
+
|
|
23
25
|
Run the migration.
|
|
24
26
|
|
|
25
27
|
```bash
|
|
@@ -90,7 +92,28 @@ You can get a hash of all stored preferences by accessing the `preferences` help
|
|
|
90
92
|
brand.preferences # => { 'featured' => false, 'display_name' => 'Wilson' }
|
|
91
93
|
```
|
|
92
94
|
|
|
93
|
-
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.
|
|
95
|
+
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. Its keys are strings, and it can be read with either strings or symbols (`brand.preferences[:featured]`). Values are stored as JSON, so read typed values through the `preferred_*` methods: a `:decimal` preference comes back as a `BigDecimal` there, while the raw hash holds its exact string (`"9.99"`).
|
|
96
|
+
|
|
97
|
+
`preferences` never holds secrets — see [Secret preferences](#secret-preferences).
|
|
98
|
+
|
|
99
|
+
## Secret preferences
|
|
100
|
+
|
|
101
|
+
Declare API keys, signing secrets and other credentials with the `:password` type:
|
|
102
|
+
|
|
103
|
+
```ruby server/app/models/my_app/gateway.rb
|
|
104
|
+
module MyApp
|
|
105
|
+
class Gateway < Spree::Gateway
|
|
106
|
+
preference :publishable_key, :string
|
|
107
|
+
preference :secret_key, :password
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
A `:password` preference works like any other — `preferred_secret_key`, `preferred_secret_key = ...`, `get_preference(:secret_key)` — but it is stored apart from the other preferences, in an encrypted `secret_preferences` column, whenever [Active Record encryption keys](../deployment/environment_variables.md#active-record-encryption) are configured. The Admin API returns it masked, showing only its last four characters.
|
|
113
|
+
|
|
114
|
+
Payment methods and integrations already have that column. To declare a secret on another model, include `Spree::SecretPreferences` and add a `secret_preferences` text column to its table; Spree refuses a `:password` preference on a model that cannot encrypt it.
|
|
115
|
+
|
|
116
|
+
Always declare a credential as `:password`. A secret declared as `:string`, or nested inside a `:hash` or `:array` preference, is stored in plain text.
|
|
94
117
|
|
|
95
118
|
## Models with preferences
|
|
96
119
|
|
|
@@ -18,7 +18,7 @@ You'll almost always want to set [`RAILS_HOST`](#urls-and-hosts) too — without
|
|
|
18
18
|
|
|
19
19
|
## Active Record encryption
|
|
20
20
|
|
|
21
|
-
Spree encrypts sensitive values at rest with [Active Record encryption](https://guides.rubyonrails.org/active_record_encryption.html): webhook endpoint signing secrets, payment gateway customer IDs, and the OAuth tokens stored on user identities. It does so only when encryption keys are configured — without them, these values are stored in plain text and a production app logs a warning at boot.
|
|
21
|
+
Spree encrypts sensitive values at rest with [Active Record encryption](https://guides.rubyonrails.org/active_record_encryption.html): payment gateway and integration secrets (API keys and webhook signing secrets), webhook endpoint signing secrets, payment gateway customer IDs, and the OAuth tokens stored on user identities. It does so only when encryption keys are configured — without them, these values are stored in plain text and a production app logs a warning at boot.
|
|
22
22
|
|
|
23
23
|
| Variable | Description |
|
|
24
24
|
| --- | --- |
|
|
@@ -45,10 +45,16 @@ After restarting your server, you can select "MyGateway" when creating a new pay
|
|
|
45
45
|
|
|
46
46
|
### Show a logo and setup guide (optional)
|
|
47
47
|
|
|
48
|
-
Payment
|
|
48
|
+
Payment methods backed by an external provider also appear in the admin dashboard under **Settings > Integrations**, next to other connected services. A method is listed there when it inherits from `Spree::Gateway`, or when its class defines `self.third_party?` to return `true`. Declare a logo and a link to your setup guide so merchants recognise the provider and know how to connect it:
|
|
49
49
|
|
|
50
50
|
```ruby app/models/my_gateway.rb
|
|
51
51
|
class MyGateway < Spree::PaymentMethod
|
|
52
|
+
# Lists MyGateway under Settings > Integrations. Not needed when the class
|
|
53
|
+
# inherits from Spree::Gateway.
|
|
54
|
+
def self.third_party?
|
|
55
|
+
true
|
|
56
|
+
end
|
|
57
|
+
|
|
52
58
|
def self.logo_url
|
|
53
59
|
'https://my-gateway.example.com/logo.svg'
|
|
54
60
|
end
|
|
@@ -49,6 +49,24 @@ Re-running is safe — `bundle exec rake spree:upgrade` figures out what still n
|
|
|
49
49
|
|
|
50
50
|
Reference material — the data backfills `bundle exec rake spree:upgrade` executes. Every task is idempotent.
|
|
51
51
|
|
|
52
|
+
### Store preferences as JSON
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
```bash Spree CLI (Docker)
|
|
56
|
+
spree rake spree:upgrade:preferences_json
|
|
57
|
+
spree rake spree:upgrade:encrypt_secret_preferences
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
```bash Without Spree CLI
|
|
61
|
+
bundle exec rake spree:upgrade:preferences_json
|
|
62
|
+
bundle exec rake spree:upgrade:encrypt_secret_preferences
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
Preferences were stored as YAML; in 6.0 they are JSON. The migration converts every `preferences` column itself, and moves gateway and integration secrets (preferences declared as `:password`) into a new `secret_preferences` column. The first task is a safety net for anything the migration could not reach — a schema changed by hand, or an extension gem installed after the migration ran. The second encrypts the moved secrets; until it runs they stay readable and are encrypted the next time their payment method or integration is saved. It does nothing until [encryption keys](#enable-active-record-encryption) are configured.
|
|
67
|
+
|
|
68
|
+
See [Preferences are stored as JSON](#preferences-are-stored-as-json) for what changes in your code.
|
|
69
|
+
|
|
52
70
|
### Convert incomplete orders into carts
|
|
53
71
|
|
|
54
72
|
```bash
|
|
@@ -181,7 +199,7 @@ Countries and states are no longer database records in 6.0. Addresses, delivery
|
|
|
181
199
|
|
|
182
200
|
## Enable Active Record encryption
|
|
183
201
|
|
|
184
|
-
Spree encrypts webhook endpoint signing secrets, payment gateway customer IDs and the OAuth tokens on user identities with [Active Record encryption](https://guides.rubyonrails.org/active_record_encryption.html) — but only when encryption keys are configured. Without keys these values are stored in plain text. New 6.0 projects get keys at setup; upgraded applications need to add them.
|
|
202
|
+
Spree encrypts payment gateway and integration secrets, webhook endpoint signing secrets, payment gateway customer IDs and the OAuth tokens on user identities with [Active Record encryption](https://guides.rubyonrails.org/active_record_encryption.html) — but only when encryption keys are configured. Without keys these values are stored in plain text. New 6.0 projects get keys at setup; upgraded applications need to add them.
|
|
185
203
|
|
|
186
204
|
**1. Make the app read the keys.** Projects created from `spree-starter` read them from the `ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY`, `ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY` and `ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT` env vars, falling back to the `active_record_encryption` entry in Rails credentials. If your `config/application.rb` predates this, add inside the `Application` class:
|
|
187
205
|
|
|
@@ -212,7 +230,31 @@ Recreate the containers so they pick up the new `.env` (`spree update`, or `spre
|
|
|
212
230
|
|
|
213
231
|
> **WARNING:** Never change or lose the keys once data is encrypted — the encrypted records become unreadable.
|
|
214
232
|
|
|
215
|
-
**3. Encrypt existing rows.** Rows written before the keys were set are plain text. OAuth tokens on user identities stay readable and are encrypted on their next write. Webhook endpoint secrets and gateway customer IDs can't be read in plain text once encryption is on — follow [Enabling encryption on an existing installation](../deployment/environment_variables.md#enabling-encryption-on-an-existing-installation): turn on `support_unencrypted_data` and `extend_queries`, deploy with the keys, run `find_each(&:encrypt)` over `Spree::WebhookEndpoint`, `Spree::GatewayCustomer` and `Spree::UserIdentity`, then turn the two settings off again.
|
|
233
|
+
**3. Encrypt existing rows.** Rows written before the keys were set are plain text. Gateway and integration secrets and the OAuth tokens on user identities stay readable and are encrypted on their next write; run `spree rake spree:upgrade:encrypt_secret_preferences` (`bundle exec rake spree:upgrade:encrypt_secret_preferences` without the Spree CLI) to encrypt every gateway and integration secret at once. Webhook endpoint secrets and gateway customer IDs can't be read in plain text once encryption is on — follow [Enabling encryption on an existing installation](../deployment/environment_variables.md#enabling-encryption-on-an-existing-installation): turn on `support_unencrypted_data` and `extend_queries`, deploy with the keys, run `find_each(&:encrypt)` over `Spree::WebhookEndpoint`, `Spree::GatewayCustomer` and `Spree::UserIdentity`, then turn the two settings off again.
|
|
234
|
+
|
|
235
|
+
## Preferences are stored as JSON
|
|
236
|
+
|
|
237
|
+
Model preferences moved from YAML to JSON, and secrets moved out of them. Declarations do not change, and the `preferred_*` methods return the same values as before. What can affect your code:
|
|
238
|
+
|
|
239
|
+
- **The raw `preferences` hash has string keys.** It still answers to symbols (`calculator.preferences[:amount]`), but `preferences.keys` returns strings. Decimals sit in it as exact strings (`"9.99"`); read them through `preferred_*`, which returns a `BigDecimal`.
|
|
240
|
+
- **Secrets are not in `preferences`.** Preferences declared `:password` live in the encrypted `secret_preferences` column. Read them with `preferred_*` or `get_preference`. A secret you assign as part of a whole hash (`update(preferences: { secret_key: ... })`) is moved there when the record is saved. To declare a secret on a model other than a payment method or an integration, see [Secret preferences](../customization/model-preferences.md#secret-preferences).
|
|
241
|
+
- **Your own preference tables need a JSON column.** The migration converts every table a model storing Spree preferences reads, including your application's own; a table another library owns is left alone. A new table should use `t.jsonb :preferences` on PostgreSQL, the default database (`t.json` on MySQL or SQLite).
|
|
242
|
+
- **Tiered calculators take a list of tiers.** `Spree::Calculator::TieredPercent` and `TieredFlatRate` store `tiers` as a list instead of a hash keyed by threshold, in Ruby and in the Admin API. The migration converts existing calculators.
|
|
243
|
+
|
|
244
|
+
```json
|
|
245
|
+
// Before
|
|
246
|
+
{ "tiers": { "100": 10, "250": 15 } }
|
|
247
|
+
// After
|
|
248
|
+
{ "tiers": [{ "threshold": "100", "value": "10" }, { "threshold": "250", "value": "15" }] }
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
`value` is a percentage for `TieredPercent` and an amount for `TieredFlatRate`.
|
|
252
|
+
- **Spree no longer allows extra classes in YAML columns.** It used to add `Symbol`, `BigDecimal` and a few time classes to `config.active_record.yaml_column_permitted_classes`. If your application serializes its own columns as YAML with those classes, add them in `config/application.rb` yourself.
|
|
253
|
+
- **Preference change methods follow Rails' naming.** Each preference is a Rails store accessor, so `preferred_<name>_changed?`, `preferred_<name>_change` and `preferred_<name>_was` work as before, while the after-save forms are Rails' own: `saved_change_to_preferred_<name>?` replaces `preferred_<name>_previously_changed?`, `saved_change_to_preferred_<name>` replaces `preferred_<name>_previous_change`, and `preferred_<name>_before_last_save` replaces `preferred_<name>_previously_was`.
|
|
254
|
+
- **Per-preference helper methods are gone.** Use `preference_type(:name)`, `preference_default(:name)` and `preference_deprecated(:name)` instead of `preferred_<name>_type`, `preferred_<name>_default` and `preferred_<name>_deprecated`. `clear_preferences`, `restore_preferences_for`, `preferences_of_type`, the class methods `preference_getter_method`, `preference_setter_method` and `prefers_query_method`, `Spree::Preferences::ScopedStore`, `Spree::Preferences::Store` and the `Spree::Preference` model are removed.
|
|
255
|
+
- **The `spree_preferences` table is dropped.** The installation id it held is not carried over: the default store generates a new one the next time it is saved. Rows an application wrote there itself are dropped with it: copy any you need before upgrading.
|
|
256
|
+
- **Preferences live only on models.** `Spree::Preferences::Preferable` is included by `Spree::Base` and needs a `preferences` JSON column; including it in a plain Ruby class is no longer supported. A hash stored inside a preference comes back with string keys.
|
|
257
|
+
- **A record whose preferences still hold YAML cannot be read.** The migration converts every row, so this only happens to rows written by older code after it ran. Run `spree rake spree:upgrade:preferences_json` (`bundle exec rake spree:upgrade:preferences_json` without the Spree CLI) to convert it.
|
|
216
258
|
|
|
217
259
|
## The Cart/Order split
|
|
218
260
|
|