1
class Assembly < ActiveRecord::Base
  has_and_belongs_to_many :parts
end

class Part < ActiveRecord::Base
  has_and_belongs_to_many :assemblies
end

コンソールの場合:

part1 = Part.new
assembly1 = Assembly.new
assembly1.parts << part1
part1.delete
Parts.all
 => []

チェックassembly1.partsすると、まだ関係があることがわかります。(!)

レコードが削除されたときにこれはどのように可能ですか?

また、アセンブリに関連付けられているパーツの削除を防ぐにはどうすればよいですか?

Rails3.0.7での作業。

4

3 に答える 3

3

ここで行っていたことはすべてメモリから行われました (データベースには何も格納されていません)。

ActiveRecorddeleteメソッドはデータベースからオブジェクトを削除しますが、そのオブジェクトを既に参照している可能性があるメモリ内の他のオブジェクトを探しません。そうすれば、assembly1.parts.delete(part1)期待通りの結果が得られる可能性が高いと思います。

オブジェクトをデータベースに保存した場合:

part1 = Part.create
assembly1 = Assembly.create(:parts => [part1])
assembly1.parts
# => [part1]
part1.delete
assembly1.parts
# => [part1]
assembly1.reload
assembly1.parts
# => []

ここで、データベース内にある場合でも、part1.deleteメモリ内コレクションを更新するか、前述の方法を使用して削除するまで、必ずしもアセンブリ オブジェクトから削除されるとは限らないことに注意してください。assembly1.parts.delete(part1)

アップデート

通常、このメソッドを使用するべきではないと思いますdelete()。ほとんど常に使用する必要がありますdestroy()delete()データベースへの削除を開始し、すべてのコールバックを無視し:dependent => :destroyます。モデル内のスタイル宣言を信じています。メソッドを使用すると、モデルdestroy()でコールバックを宣言できます。before_destroy

class MyClass
  has_and_belongs_to_many :foos

  before_destroy :allow_destroy

  def allow_destroy
    foos.empty?
  end
end

それがアセンブリの一部である場合、それを破壊しないという要件が得られるはずです。delete()コールバックを無視するため、実行 を停止することはできません: ActiveRecord::Relation#delete ドキュメント

モデル コールバックに関する詳細情報(ドキュメント)

于 2012-04-10T20:40:26.417 に答える
0

:dependent => :destroyコントローラーに追加する必要があります。

于 2012-04-10T20:40:13.367 に答える