Skip to main content

Overview

Adding a rule — and occasionally relaxing one Spree ships — is one of the most common reasons to reach into core models. There are three ways to do it, and picking the right one is mostly a question of what kind of rule you have. Spree deliberately has no registry for adding or removing arbitrary model validations. Adding one with a decorator is already a single line of ordinary Rails, and removing a core rule is served by the knobs below.

Vetoing an operation

This is the one to reach for first. A validate hook runs inside the flow, before anything is written, and can stop it:
Why this beats a model validation for operational rules: it runs only for the operation you targeted, so a data migration or an admin correction isn’t fought by a customer-facing rule; it sees the whole flow, not one record; and it can tell staff from customers (workflow.created_by) to allow a supervisor override. Both cart keys appear above because adding to a cart and setting a quantity are different flows. See Services & Workflows for the full hook list.

Relaxing a rule Spree ships

Never call clear_validators! — it wipes every validation on the model, including ones added by other extensions, and the breakage appears far from the cause. Use one of these instead.

Store preferences

Some rules are switchable per store, with no code at all. Change them in the dashboard under Settings → Store, or through the Admin API:
All four are editable in the dashboard except address_requires_company, which is API-only for now.

The address validator registry

Address rules are regional and business-specific, so addresses carry a registry of extra validator classes you can add to and remove from:
A validator is an ordinary ActiveModel::Validator:
Register your own classes from config.to_prepare rather than an initializer — the registry holds classes, and a reloadable constant registered once at boot goes stale on the next reload.

Checkout requirements

Rules about what a cart needs before it can be completed — a phone number before delivery, a purchase order number for B2B — belong in the checkout requirements registry rather than a model validation, because they also drive what the storefront shows as outstanding:
See the customization quickstart for the full registry API.

Custom field values

Custom fields currently validate their type only — a Number field rejects non-numbers, a Json field rejects malformed JSON. There is no per-definition length, range or format rule yet. A product type marking a custom field as required is an advisory marker shown in the dashboard; the server does not enforce it.