Jak zapobiec usunięciu rodzica, jeśli ma rekordy potomne?

Przejrzałem poradniki Ruby on Rails i nie wiem, jak zapobiec usunięciu rekordu rodzica, jeśli ma dzieci. Na przykład. Jeśli w mojej bazie danych znajdują się klienci i każdy klient może mieć wiele zamówień , chcę zapobiec usunięciu klienta, jeśli ma on jakiekolwiek zamówienia w bazie danych. Powinni mieć możliwość usunięcia klienta tylko wtedy, gdy nie ma on zamówień.

Czy istnieje sposób definiowania związku między modelami do wymusić takie zachowanie?

Author: Rob, 2010-10-29

4 answers

Możesz to zrobić w wywołaniu zwrotnym:

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

EDIT

Zobacz ta ODPOWIEDŹ dla lepszego sposobu, aby to zrobić.

 44
Author: zetetic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:55:09
class Customer < ActiveRecord::Base
  has_many :orders, :dependent => :restrict # raises ActiveRecord::DeleteRestrictionError

Edit: od Rails 4.1, :restrict nie jest poprawną opcją, a zamiast tego powinieneś użyć :restrict_with_error lub :restrict_with_exception

Np.:

class Customer < ActiveRecord::Base
  has_many :orders, :dependent => :restrict_with_error
 87
Author: Mauro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-05 03:02:32

Spróbuj użyć filtrów , aby podłączyć kod niestandardowy podczas przetwarzania żądania.

 0
Author: Joseph Weissman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-29 16:58:29

Jedną z możliwości byłoby uniknięcie podawania użytkownikom linku do usunięcia w tym scenariuszu.

link_to_unless [email protected]?

Innym sposobem byłoby poradzenie sobie z tym w kontrolerze:

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

Lub, jak sugeruje Joe, before_filters może działać dobrze tutaj i prawdopodobnie będzie znacznie bardziej suchym sposobem na to, zwłaszcza jeśli chcesz tego typu zachowania dla większej liczby modeli niż tylko Klienta.

 0
Author: Samo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-29 16:59:21