ユカシカド エンジニアブログ

体の栄養状態を把握する検査サービス VitaNoteを開発するエンジニアのブログ

(翻訳)Spreeドキュメント - ロジックのカスタマイズ

翻訳元:LOGIC CUSTOMIZATION - SPREE DEVELOPER

(翻訳)Spreeドキュメント - Viewのカスタマイズに 続いてロジックのカスマイズについて。

※ 誤訳意訳多々注意

自分の残念な英語力ではぴんとこない箇所は英語のままpending。怪しい訳多し。

実践もしくは英語力の向上を伴って正しく理解することがあれば、加筆・修正する予定です。

この記事は2013/07/15現在のものです。

翻訳元:LOGIC CUSTOMIZATION - SPREE DEVELOPER

概要

  • Spreeの既存のモデル、コントローラーの拡張、オーバーライド
  • 既存のSpreeコントローラーからのアウトプットを変更する方法
  • 画像操作のカスタマイズ

クラスの拡張(original)

全てのSpreeのビジネスロジック(モデル、コントローラー、ヘルパー、etc)は標準のRubyイディオムを使用して 自分の要件に合わせてオーバーライド、拡張することができます。

自分のアプリケーション/エクステンションへ変更するような場合は、変更の対象となる元のクラス名に’_decorator'を付け足してapp/modelsやapp/controllersにファイルを作成するのが標準的な方法です。

Productモデルにカスタムメソッドを追加する場合: app/models/product_decorator.rb

Spree::Product.class_eval do
  def some_method
    ...
  end
end

Productコントローラーにカスタムメソッドを追加する場合: app/controlers/product_controller_decorator.rb

Spree::ProductsController.class_eval do
  def some_action
    ...
  end
end

これらと同じフォーマットで既存のメソッドを再定義することができます。

Productデータへのアクセス

Productコントローラーへ新しいメソッドを追加する場合、Productデータへ頻繁にアクセスすることになるでしょう。'before_filter :load_data'を使うことで実現できます。

Spree::ProductsController.class_eval do
  before_filter :load_data, :only => :some_action

  def some_action
    ...
  end
end

:load_dataはそのパーマリンクによってProductを見つけるのにparams[:id]を使います。

レスポンスのオーバーライド(original)

Spree 0.60.0 ではメソッドを完全にオーバーライドする必要なく、既存のコントローラーの出力をオーバーライドしたり変更する方法をサポートしています。

respond_overrideメソッド

respond_overrideメソッドはRails3のrespond_withメソッド(現在全てのSpreeコントローラーで使われている)でアクションからのレスポンスをカスタマイズします。以下のようなシンタックスでオプションをハッシュにしてわたすことができます。

respond_override :action_name => { :format =>  { :result => lambda { ... response ... } } }
  • :action_name - そのレスポンスを定義するコントローラーに存在しているアクション( :update, :create, :new)
  • :format - リクエストのフォーマット(:html, :json, :js, etc)。Spreeのコントローラー全てが持っているrespond_toメソッドを呼び出す際にどのフォーマットでレスポンスを返すか定義します。
  • :result - :successか:failureが当てはまります。:successはほとんどのアクションでデフォルトになっています。しかし、モデルのアップデート時にバリデーションに失敗する場合はモデルを作成したり変更したりするアクションは:failureになるでしょう。
  • lambda - カスタムレスポンス(renderやredirect_to)を返すことが期待される実体コードが含まれるような無名関数を指定。匿名関数は正しいタイミングで確実に評価されなければなりません。

使い方

ProductsController#indexで独自の部分テンプレートを表示させたい時はapp/controllers/products_controller_decorator.rbに以下のように書きます。

Spree::ProductsController.class_eval do
  respond_override :index => { :html =>
    { :success => lambda { render 'shared/some_file' } } }
end

Admin::ProductsControllerでエラー時にリダイレクトさせたい場合などはこのように書きます。

Spree::Admin::ProductsController.class_eval do
  respond_override :create => { :html => { :failure => lambda {
    redirect_to some_url } } }
end

注意

  • アクションがレスポンスを定義する為にrespond_withを使用していなければ、respond_overrideは動作しません。
  • Some actions contain several respond_with calls so any respond_override defined on it will be executed for any of the respond_with instances, so it’s important to check the model state / logic within the lambda passed to prevent overriding all possible responses with the same override.

Productの画像

Spreeは画像を管理する為にThoughtbotのgem、paperclipを使用しています。paperclipの全てのオプションはSpree::Imageクラスにあります。もし、Productとサムネイルのデフォルトのサイズを修正したければ、アプリケーションのモデルのディレクトリにimage_decorator.rbを作成して以下のように書くだけで変更できます。

Spree::Image.class_eval do
  attachment_definitions[:attachment][:styles] = {
    :mini => '48x48>', # thumbs under image
    :small => '100x100>', # images on category view
    :product => '240x240>', # full product image
    :large => '600x600>' # light box image
  }
end

テンプレートで使用するサイズを任意で追加することもできます。(例: カートページで使う場合に :micro とするように)

画像リサイズオプションの書き方

デフォルトではアスペクト比を維持するように動作します(例えば、:product が480x400 であれば、240x200になるでしょう)。よく以下のようなオプションが使用されています: - 末尾を # にすると、画像は指定したサイズで中心から切り取られます。 - 末尾を > にすると、画像が指定したサイズより大きい場合は調整されます(例えば、 サムネイルとして:small =>100x100 としている場合は画像は変更されません) 。