spree/spree · warning

Spree::StoreCredit.order_by_priority is deprecated and will

Error message

Spree::StoreCredit.order_by_priority is deprecated and will be removed in Spree 6.1. Use .oldest_first instead.

What it means

StoreCredit.order_by_priority was the 5.x scope that spent credits by their type's priority. 6.0 deletes store credit types entirely, so redemption order is now fixed: oldest first. The old scope delegates to .oldest_first (order(:created_at, :id)) and warns; removed in 6.1.

Source

Thrown at spree/core/app/models/spree/store_credit.rb:43

    belongs_to :originator, polymorphic: true, optional: true

    has_many :store_credit_events, class_name: 'Spree::StoreCreditEvent'
    has_many :payments, as: :source, class_name: 'Spree::Payment'
    has_many :orders, through: :payments, class_name: 'Spree::Order'

    validates :currency, :store, presence: true
    validates :amount, numericality: { greater_than: 0 }
    validates :amount_used, numericality: { greater_than_or_equal_to: 0 }
    validate :amount_used_less_than_or_equal_to_amount
    validate :amount_authorized_less_than_or_equal_to_amount

    delegate :email, to: :created_by, prefix: true, allow_nil: true

    # Redemption order: the oldest credit is spent first.
    scope :oldest_first, -> { order(:created_at, :id) }
    # @deprecated Removed in Spree 6.1 — store credit types are gone; use {.oldest_first}.
    scope :order_by_priority, lambda {
      Spree::Deprecation.warn('Spree::StoreCredit.order_by_priority is deprecated and will be removed in Spree 6.1. Use .oldest_first instead.')
      oldest_first
    }

    scope :not_authorized, -> { where(amount_authorized: 0) }
    scope :not_used, -> { where("#{Spree::StoreCredit.table_name}.amount_used < #{Spree::StoreCredit.table_name}.amount") }
    scope :available, -> { not_authorized.not_used }
    scope :with_gift_card, -> { where(originator_type: 'Spree::GiftCard') }
    scope :without_gift_card, -> { where(originator_type: [nil, '']).or(where.not(originator_type: 'Spree::GiftCard')) }

    after_save :store_event
    before_destroy :validate_no_amount_used

    attr_accessor :action, :action_amount, :action_originator, :action_authorization_code

    extend Spree::DisplayMoney
    money_methods :amount, :amount_used, :amount_remaining, :amount_authorized

    def amount=(amount)

View on GitHub (pinned to 06bf66a868)

Solutions

  1. Replace .order_by_priority with .oldest_first — the resulting order is identical to what production now uses.
  2. Delete any custom prioritizer that sorted by type priority; priority no longer exists.
  3. Update extensions to their Spree 6 releases.
  4. Bridge dual-version with respond_to?(:oldest_first) on the class.

Example fix

# before
credits = store_credits.available.order_by_priority

# after
credits = store_credits.available.oldest_first
Defensive patterns

Strategy: fallback

Validate before calling

scope = if Spree::StoreCredit.respond_to?(:oldest_first)
  Spree::StoreCredit.available.oldest_first
else
  Spree::StoreCredit.available.order_by_priority
end

Prevention

When it happens

Trigger: Calling Spree::StoreCredit.order_by_priority — typically checkout code or extensions selecting which credits to capture, e.g. Spree::StoreCredit.available.order_by_priority.each { ... }.

Common situations: Store-credit spenders/prioritizers copied from 5.x; extensions implementing custom credit redemption; specs asserting capture order.

Related errors


AI-assisted analysis of spree/spree@06bf66a868 (2026-08-21). Data as JSON: /api/errors/aa672668a59d1e47. Report an issue: GitHub.