親子モデル同時更新でバリデーションエラーになった時、順序を持つ子モデルの並び順をなんとかしたい

rails4

順序を持つ子モデル(猫クラス)はpositionカラムが持っていて、親モデル(人間クラス)には次みたいなに関連が定義されると思う。

class Human < ActiveRecord::Base
  has_many :cats, -> { order(:position) }
  accepts_nested_attributes_for :cats
end

DBから取ってくるのであればpositionで並び替えられるんだけど、
バリデーションエラーの時みたいな下記のケースではpositionで並ばない。

# sortableな画面からのPOSTを受け取る
params[:human] # => [0] => { id: nil, positio: 1 },  [1] => { id: 1, position:2 },  [2] => { id: 2, position:3 } 
@human.update(human_params) # => バリデーションエラー
@human.cats # => [[#<Cat id: 1 position: 2>, [#<Cat id: 2 position: 3>], [#<Cat id: nil position: 1>] 

バリデーションエラーになると、idを持っていない猫インスタンスが最後に並んでしまう。

とりあえずこういうの定義した。

class Human < ActiveRecord::Base
...
  def cats
    if self.errors.present?
      super.sort_by { |x| x.position }
    else
      super
    end
  end
...
end

結論

クライアント側でバリデーション頑張る。