spree-data-model について
spree-data-model は、Spree のモデルを扱う開発者向けのリファレンススキルです。商品カタログ、注文、チェックアウト、ストア、チャンネル、市場の関係を整理し、クエリや API 利用に関わる実装上の要点を示します。
主な機能
- 01カタログから注文までのモデル関係
- 02ストア、チャンネル、市場の構造
- 03チェックアウトと決済モデルの概要
- 04API のプレフィックス付き ID 規約
- 05状態フィールドとリクエストコンテキストの説明
活用シーン
- 01商品からカートや注文までのモデルを追跡
- 02販売チャンネル別の商品検索
- 03進行中のカートと完了注文の区別
- 04コードでのモデル ID とリクエストコンテキストの利用
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ spree/ agent-skills --skill spree-data-modelインストール後、Claude Code で/spree-data-modelを入力して読み込まれたか確認します。
詳細
Spree データモデル
よく質問される Spree モデルの関係図です。フィールドレベルのドキュメントは、インストール済みの @spree/docs パッケージの node_modules/@spree/docs/dist/developer/core-concepts/ にあります。
カタログ → カートのパイプライン
Product → Variant → LineItem → Order
- Product はブランドレベルのエンティティです(名前、スラッグ、説明、カテゴリ)。
- Variant は販売可能な SKU です。すべての Product には少なくとも 1 つの Variant があります。Variant には SKU、価格、寸法があり、在庫に紐づきます。
- LineItem は
quantityと追加時点で固定された価格を持ち、Variant を Order に紐づけます。 - Order は顧客の取引です。処理中はカートであり、チェックアウト後は完了した取引です(同じレコードで、
stateが異なります)。
Variant は、各 Variant と StockLocation の組み合わせごとに 1 つ作成される StockItem と、StockMovement の履歴を介して在庫に関連付けられます。
マスターとデフォルトの Variant
Product には master Variant(レガシー概念で、is_master: true)と、算出される default_variant メソッドがあります。Spree::Config[:track_inventory_levels] が有効な場合は最初の購入可能な Variant、無効な場合は position 順で最初の非マスター Variant が返されます。マスターは、Product にほかの Variant がない場合に限りフォールバックとして使われます。product.default_variant_id は、算出された Variant の ID を返すだけです。5.5 ではどちらもデータベースのカラムではありません。default_variant_id に対するクエリやマイグレーションは行わないでください(spree_products の default_variant_id FK は 6.0 で予定されていますが、実装はまだ始まっていません。docs/plans/6.0-remove-master-variant.md を参照してください)。マスター以外の販売可能な Variant には product.variants を使用し、マスターの行も含める必要がある場合にのみ product.variants_including_master を使用してください。
マルチチャネル/マルチストアの軸
Store → Channel → ProductPublication → Product
Spree 5.5 以降で利用できます。
- Store は最上位のブランドです(通常、1 つの組織につき 1 つの Store です)。
- Channel は Store 内の販売チャネルです。オンラインストア、対面販売の POS、マーケットプレイス連携(Amazon、eBay)、B2B 卸売、モバイルアプリなどがあります。すべての Store には、少なくとも「Online Store」という名前のデフォルト Channel があります。
- ProductPublication は中間モデルで、どの Product がどの Channel に表示されるかを管理します。スケジュール設定用に、任意で
published_at/unpublished_atの期間を指定できます。 - Order には
channel_idがあり、チャネルごとに売上を集計できます。
Store API は、各リクエストの X-Spree-Channel ヘッダーから Channel を特定します(channels.code または ch_… が先頭に付いた ID と照合します)。ヘッダーがない場合は、Store のデフォルト Channel が使用されます。Admin API は X-Spree-Channel を使用しません。管理者のクエリでは、現在の Store に属するすべての Channel のデータが返されます。
マーケット(地域設定)
Market has_many :countries
Market columns: currency (string), default_locale (string)
Order belongs_to :market
Market は、国、通貨、デフォルトのロケールをまとめた地域設定です。通常、作成時にデフォルトの国がわかっている場合、Store にはデフォルトの Market が自動的に作成されます。ただし、Market は任意です。store.has_markets? で確認してください。Market がない場合、通貨とロケールは Store レベルのデフォルト値にフォールバックします。Order は Market で作成されます。Market によって、顧客に表示される通貨と適用される税ルールが決まります。
Market の詳細については、node_modules/@spree/docs/dist/developer/core-concepts/markets.md を参照してください。
カートと Order
Spree では、Spree::Order は処理中のカートと完了した取引の両方を表します。state カラムで段階を管理します:cart、address、delivery、payment、confirm、complete。状態で絞り込むことで区別できます。
Spree::Order.where(state: 'cart') # in-progress carts
Spree::Order.where(state: 'complete') # finalized orders
Spree::Order.complete # named scope — NOT equivalent: defined as where.not(completed_at: nil), so it matches any order that ever completed checkout, including ones later canceled or returned
Order#token(has_secure_token :token, length: 35)は、リクエストをまたいで匿名カートを識別します。ログイン済みユーザーのカートは user_id FK で紐づけられます。
チェックアウト関連モデル
Order → Payment → PaymentMethod
Order → Shipment → ShippingRate → ShippingMethod
Order → Address (bill_address, ship_address)
- Payment は独自の状態マシンを持ちます(
checkout → processing → pending → completedのほか、failed、void、invalidがあります)。カラムはstateです。 - Shipment は独自の状態マシンを持ちます(
pending → ready → shipped。canceledもあります)。カラムはstateです。 - ShippingRate は Shipment ごとの配送方法の提示です(例:UPS Ground 5.99 ドル、USPS Priority 8.99 ドル)。顧客が 1 つを選択します。
顧客/ユーザー
Spree.user_class (typically Spree::User)
↓
Address (many, via spree_addresses)
CreditCard (many)
GiftCard (many)
StoreCredit (many)
ユーザーモデルを参照する際は Spree.user_class と Spree.admin_user_class を使用してください。Spree::User を直接使用しないでください。アプリでは、設定によって独自のユーザーモデルに差し替えられます。
調整(ポリモーフィック)
Adjustable (Order, LineItem, Shipment) ← Adjustment
Adjustment はポリモーフィックで、adjustable_type と adjustable_id を介して、任意の Order、LineItem、または Shipment に紐付きます。各 Adjustment には、作成元(TaxRate、PromotionAction、ReturnAuthorization など)を示す source と、作成元の型で絞り込むための組み込みスコープがあります。
order.adjustments.tax # source_type: 'Spree::TaxRate'
order.adjustments.promotion # source_type: 'Spree::PromotionAction'
order.adjustments.return_authorization
order.all_adjustments # adjustments on order + its line_items + shipments
プレフィックス付き ID
v3 API で公開される Spree のすべてのモデルには、Stripe 形式のプレフィックス付き ID があります。
product.prefixed_id # => "prod_86Rf07xd4z"
order.prefixed_id # => "or_m3Rp9wXz"
variant.prefixed_id # => "variant_k5nR8xLq"
ID は Sqids を介して整数の PK から計算されます。データベースのカラムはありません。プレフィックスは、モデル上で has_prefix_id :<prefix> を使ってクラスごとに宣言します。v3 API はあらゆる場所でプレフィックス付き ID を受け付け、返します。find_by_prefix_id! を使うと、整数の PK に戻せます。
プレフィックスの規則:
- 一部のリソースでは長い形式:
prod(Product)、variant(Variant) - その他の大半では短いコード:
or(Order)、py(Payment、Stripe との整合性)、adj(Adjustment)、li(LineItem)、ctg(Category/Taxon)、cus(顧客、Stripe との整合性)、ch(Channel)、mkt(Market)
API レスポンスで生の整数 PK を公開しないでください。
state と status(5.5 では混在)
モデルによって、導入時期に応じて異なるカラム名が使用されています。
Order.state、Payment.state、Shipment.state— 古いステートマシンOrderApproval.status— 新しい status カラムChannelはステートマシンを使用せず、代わりにactiveの真偽値を持ちます
モデルコードを書くときは、そのモデルが実際に持つカラムの規則に従ってください。クエリを作成するときに確信がない場合は、モデルのソースを確認してください。
Spree::Current(リクエストごとのコンテキスト)
ストア/通貨/ロケールを引数として渡すのは避けてください。代わりに、暗黙のコンテキストを使用します。
Spree::Current.store # The store handling this request
Spree::Current.currency # The currency to display prices in
Spree::Current.locale # The locale for translations
Spree::Current.channel # The resolved sales channel (falls back to the store's default channel)
Spree::Current.market # The resolved market (falls back to the store's default market)
モデル、コントローラー、ジョブ、サービスで利用できます。API ではコントローラーの before_action によって自動設定されます(Spree::Current 内でストアのデフォルト値へのフォールバックも組み込まれています)。特定のストアを対象とする必要があるジョブや rake タスクでは、手動で設定します。
さらに読む場合
- フィールドレベルのドキュメント: 各モデルの
node_modules/@spree/docs/dist/developer/core-concepts/<topic>.md。 - OpenAPI 仕様:
node_modules/@spree/docs/dist/api-reference/store.yamlに、すべての API フィールドとその型が記載されています。モデルのソースから推測するより確実です。 - 新しいモデル/API リソースの追加:
spree-resourceスキルを使用してください。 - 既存の Spree モデルの拡張(デコレーターによる関連、バリデーション、スコープ、メソッドの追加):
spree-decoratorsスキルを使用してください。