MOE3: Order モデル実装

スキーマ

viaconvoysample のデフォルト値は false

  create_table "orders", force: true do |t|
    t.integer  "player_id"
    t.integer  "unit_id"
    t.integer  "destination_id"
    t.boolean  "viaconvoy",      default: false
    t.integer  "target_id"
    t.boolean  "sample",         default: false
    t.string   "type"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

Order クラス

デリゲーター Order#province を定義。

tareget 関連の小細工は勢いだけで書いたので、ちゃんとテストしないと心配。

もうちょっと綺麗に書けないものか。

class Order < ActiveRecord::Base
  extend Forwardable

  belongs_to :player
  belongs_to :unit
  belongs_to :destination, class_name: "Province"
  belongs_to :target, class_name: "Order", dependent: :destroy

  # Order#province を定義
  def_delegator :unit, :province

  # target に渡された Order は自動的に複製される
  alias_method :association_target=, :target=
  def target=(target)
    return unless target
    self.target.destroy if self.target
    sample = target.dup
    sample.sample = true
    self.association_target = sample
    save! if persisted?
  end
end

もちろん targettarget=SupportOrderConvoyOrder でしか使わない。後々問題になるようなら HoldOrderMoveOrder のは塞ぐけど、実害がなければこのまま放置。

ところで、Order#target= の戻り値を複製された sample: true のオブジェクトにしたかったのだが、どうも Ruby の Setter メソッドの戻り値は変更できないようだ。特に必要はないので別に構わないんだけど。

HoldOrder クラス

今は書くことなし。

class HoldOrder < Order
end

MoveOrder クラス

MoveOrder#srcMoveOrder#dst も定義。

一見すると似たようなメソッドなのに、どちらも通常のメソッド定義じゃないところが面白い。

class MoveOrder < Order
  # MoveOrder#src を定義
  def_delegator :unit, :province, :src

  # MoveOrder#dst を定義
  alias_method :dst, :destination
end

SupportOrder クラスと ConvoyOrder クラス

今は書くことなし。

class SupportOrder < Order
end
class ConvoyOrder < Order
end