2

保存時に MongoDB オブジェクト内の埋め込みドキュメントのセット全体を置き換えられるようにしたい - HTML フォームには新しいセット全体が含まれます。

また、保存する前にすべてを検証する必要があります。つまり、古いドキュメントを破棄せず、追加されるたびに検証します。

実装を思いつきましたが、永続的ではありません。新しい埋め込みドキュメントは表示されません。さらに複雑なのは、継承が関係していることです。これが(簡略化された)私がこれまでに持っているモデルのセットです:

class Person
  include Mongoid::Document
  embeds_many :vehicles
end

class Vehicle 
  include Mongoid::Document
  embedded_in :person
end

class Car < Vehicle
end

class Motorbike < Vehicle
end

ユーザーがフォームを送信したときにどのような手段をインスタンス化するかを決定するために、このメソッドを Person クラスに追加しました。

def build_from_hash(hash)
   @vehicles= []
   hash.each do |idx, vehicle|
      if vehicle[:_type].constantize < Inclusion # Check for inheritance, for security
         self.vehicles.push vehicle[:_type].constantize.new(vehicle)
      end
   end
end

そして、それを呼び出すようにコントローラーを変更しました:

def submit_build
  @person= current_user.persons.find(params[:id])
  @person.build_from_hash(params[:vehicles]) if params.has_key? :vehicles

  respond_to do |format|
    if @person.save # Also tried: @person.update_attributes(inclusions: @person.vehicles)
      format.html { redirect_to @person, notice: 'Person was successfully updated.' }
      format.json { head :no_content }
    else
      format.html { render action: "build" }
      format.json { render json: @person.errors, status: :unprocessable_entity }
    end
  end
end

エラーは発生しませんでした。ページは正常に動作したかのようにリダイレクトされますが、もう一度調べてみると、埋め込まれたドキュメントはありません。

Rails 3.2.8、Mongoid 3.0.5、MongoDB 1.8.3 を使用。

4

1 に答える 1

0

これをより標準的なRails風の方法で行う方法を見つけましたが、いくつかの奇妙な動作の回避策があります.

短い答え: Person クラスが必要でaccepts_nested_attributes_for :vehiclesあり、コントローラーからすべてのカスタム要素を削除して、アクションを標準の更新アクションに置き換える必要がありました。しかし、Rails プロセスがこれらの各サブクラスのオブジェクトを既にインスタンス化していない限り、Vehicle のサブクラスのパラメーターを受け入れないため、_type次のような初期化子を使用して回避する必要がありました。

Car.new
Motorbike.new

長い答えはMongoid Google group にあります。

于 2012-09-28T19:33:24.193 に答える