fv17の日記

Webエンジニアの備忘用ブログです。主にWeb界隈の技術に関して書いています。

Solidus - Productsまわりの概念まとめ

Solidus、Spreeにおける、Productsに関するまとめ。

SpreeのDevelopers Guideの意訳を元に、SolidusのDevelopers Guideや自分で実装して確認した内容を備忘用にまとめています。

最初にお詫び

手探りで読みながら試しているため、誤った記述の可能性があります。実装する時は公式docを参照してください。本記事は誤った記述があることを前提に日本語でザッと読んでイメージを掴む等に使って頂ければ。

商品(Product)に関連するモデルの概要

Productとは

SolidusにおけるProductとは商品のこと。その商品に関する一般的な情報を保持している。マグカップとTシャツを売ろうとするならば、別々の商品として設定する。

Variantsとは

ある商品の特性のこと。例えば、洋服のS、M、Lなどのサイズや青、白といったカラーのことで、Variantsが異なれば在庫管理を別々に行ったり、異なる価格を付けたりすることができる。1つのProductに対して、複数のVariantsを紐づけることができる。

Option TypeとOption Valueとは

ある商品の特性は、正確にはVariantに紐づいているOption TypeとOption Valueで表現される。例えば、Option Typeが「サイズ」を表し、Option Valueが「M」という具合。1つのVariantに対して、Option TypeとOption Valueの組み合わせは複数紐づけられる場合もあり、例えば、「サイズ」が「M」という1セットと、「カラー」が「青」という1セットが紐づくなど。

Product

Productの属性

  • name : 名前。
  • description : 商品説明。商品ページとかに表示
  • permalink : 商品詳細ページへのURL
  • available_on : ストアで利用可能(買えるよう)になる日付。未設定の場合、表示されないので注意
  • deleted_at : available_onの逆。ストア上で利用できなくなる日付
  • meta_description : サーチエンジン向けの説明。SEO
  • meta_keywords : サーチエンジン向けのキーワード。コンマ区切り。SEO
  • meta_title:HTMLのtitleタグ用。空欄の場合、nameが代用される

Variant

master variant と normal variant の2種類がある

master variant

全ての商品が必ず一つ持ち、商品を新しく作った際に自動で作られる。基本的な情報を保持しており、master variantsに設定されている価格などは、新しくnormal variantが作成された場合に引き継がれる。is_masterプロパティでそのvariantがmaster_variantか確認できる。

normal variants

Option Types と Option Values の組み合わせでユニークになる商品の特性。価格などの設定はmaster variantのものが引き継がれ、こちらで独自に設定した場合は上書きされる。具体例としては、あるTシャツのサイズがSとM、色が白と青ならば下記4通りの組み合わせが考えられる。

  • Sサイズ × 白
  • Sサイズ × 青
  • Mサイズ × 白
  • Mサイズ × 青

Variantの属性

  • weight, height, width, and depth:項目名称のまま
  • cost_currency:原価計算時の貨幣
  • cost_price:製造コスト
  • position:表示順
  • track_inventory:在庫管理するか否か
  • tax_category_id:productのtax categoryを上書き

master variantの取得のコード

Spree::Product.find(1).master
# => <Spree::Variant id: 2, is_master: true, ...>

その他、variants取得時にmasterも欲しい場合は variants_including_master 、不要な場合は variants でアクセス。

Option Types と Option Values

Variantsを理解するためには、option types と option values の理解が必要。
Option Types:商品の特性のこと。例えば、サイズや色。一つの商品に対し、複数設定することができる
Option Values:特性の値。例えば、サイズに対するS・M・L、色に対する白・赤・青

Image

商品の画像。Spree::Imageモデルで管理される。master variantsに全てのvariantsで共通の画像が紐づいており、特性毎に異なる画像の場合はnormal variantsに紐づいでいる。たとえば、自動車の場合、車体の画像はカラーが異なるためnormal variantsに紐付け、車内画像は同一になるためmaster variantsに紐づける。なお、SolidusではPaperclip gem使っており、同一画像を複数サイズで管理している。

Imageの属性

  • viewable_id:その画像に紐づいているvariantのID。なぜvariant_idじゃないのか...謎
  • position:画像が表示される順番
  • alt:alt属性の値。画像の説明
# product(master variant)に紐づく画像をsmallサイズで表示
product.display_image.attachment(:small)

# variantsに紐づく画像を取得
product.variant_images

Product Properties

商品の属性を表し、一商品に対し複数設定することが可能。Variantsと混同しやすいが、こちらは単に商品の付加情報。例えば、ある洋服は異なるサイズ(Variants)を持つが、素材が綿100%であることは共通である場合、その商品のpropertyは「素材:綿100%」となる。

product.property("material")
# => "100% Cotton"

Multi-Currency Support

価格は、貨幣とvariantの組み合わせで決まる。特定の貨幣における、variant毎の価格が存在しない場合、そのvariantはstore上に表示されない。

現在の貨幣でその商品が幾らであるかはpriceメソッドで取得可。

# 商品価格を取得 (master variantの価格を取得)
product.price

# Variants毎の価格を取得
Spree::Variant.find(1).price

貨幣毎の価格を得たい場合には、

Spree::Product.find(1).prices
# => [#<Spree::Price id: 2 ...]
#    [#<Spree::Price id: 3 ...]

Spree::Variant.find(1).prices
# => [#<Spree::Price id: 4 ...]
#    [#<Spree::Price id: 5 ...]

Prototypes

商品が非常に多い場合に、OptionType と Property を商品毎に設定するのは困難。Prototypesでデフォルト設定的なものを作成することができる。

Taxons and Taxonomies

Solidusでは商品をツリー構造(階層構造)のカテゴリーに分けることができる。理解しなければならないのは、Spree::TaxonomysとSpree::Taxonの2つ。

用途に応じて、複数のツリー構造を作ることができるが、その一つ一つのツリーのことをTaxonomyと呼ぶ。デフォルトSeedを投入すると、CategoriesとBrandという2つのTaxonomyが作成されているはず。Taxonは各ツリーのノードのこと。Categoriesが下記のように分かれていたら、その一つ一つの要素がTaxon。

# CategoriesというTaxonomy
Categories
|-- Luggage
|-- Clothing
    |-- T-shirts  # このT-shirtsなど一つ一つのノードをtaxon
    |-- Socks
|-- Shoes

# BrandsというTaxonomy
Brands
|-- Adidas
|-- Bentley
|-- Calvin Klein

階層構造は入れ子集合モデルを元に設計されており、詳しく知りたい場合は下記。また、awesome_nested_set Gemを用いて実装しているため、そちらも参照するとより理解が深まる。

第5回 SQLで木構造を扱う~入れ子集合モデル (1)入れ子集合モデルとは何か :SQLアタマアカデミー|gihyo.jp … 技術評論社
第5回 SQLで木構造を扱う~入れ子集合モデル (2)入れ子集合モデルにおける検索 :SQLアタマアカデミー|gihyo.jp … 技術評論社
第5回 SQLで木構造を扱う~入れ子集合モデル (3)入れ子集合モデルにおける更新 :SQLアタマアカデミー|gihyo.jp … 技術評論社
GitHub - collectiveidea/awesome_nested_set: An awesome replacement for acts_as_nested_set and better_nested_set.