web-dev-qa-db-ja.com

子レコードがある場合、親の削除を防ぐにはどうすればよいですか?

私はRuby on Railsガイドで調べましたが、Childrenがある場合に、誰かがParentレコードを削除できないようにする方法を理解できません。たとえば、データベースに[〜#〜] customers [〜#〜]があり、各顧客が複数の[〜#〜] orders [〜#〜]を持つことができる場合、データベースに注文がある場合、誰かが顧客を削除できないようにしたいのですが、顧客が注文を削除できないのは、注文がない場合のみです。

この動作を実施するためにモデル間の関連付けを定義する方法はありますか?

46
Rob

コールバックでこれを行うことができます:

class Customer < ActiveRecord::Base
  has_many :orders
  before_destroy :check_for_orders

  private

  def check_for_orders
    if orders.count > 0
      errors.add_to_base("cannot delete customer while orders exist")
      return false
    end
  end
end

編集

これを行うためのより良い方法については this answer を参照してください。

47
zetetic
class Customer < ActiveRecord::Base
  has_many :orders, :dependent => :restrict # raises ActiveRecord::DeleteRestrictionError

編集:現在Rails 4.1、:restrictは有効なオプションではなく、代わりに:restrict_with_errorまたは:restrict_with_exceptionを使用する必要があります

例えば。:

class Customer < ActiveRecord::Base
  has_many :orders, :dependent => :restrict_with_error
99
Mauro

filters を使用して、リクエスト処理中にカスタムコードをフックしてみてください。

0
Joseph Weissman

このシナリオでは、ユーザーに削除へのリンクを提供しないようにすることもできます。

link_to_unless [email protected]?

別の方法は、コントローラーでこれを処理することです。

if [email protected]?
  flash[:notice] = "Cannot delete a customer with orders"
  render :action => :some_action
end

または、Joeが示唆しているように、before_filtersはここでうまく機能する可能性があり、おそらくこれよりはるかに多くのDRY方法です)。

0
Samo