2012-01-11 8 views
8

Mam przesyłki i faktury.Szyny 3. przed sprawdzaniem oryginalności, aby zapobiec usuwaniu rekordów nadrzędnych.

faktury należy do wysyłki
przesyłka ma jedną fakturę

Jeśli przesyłka ma fakturę, wówczas przesyłka nie powinien móc zostać usunięte. Muszę ustawić to w modelach, ponieważ używam ActiveAdmin.

Więc zrobiłem to w shipment.rb

has_one :invoice 
before_destroy :check_for_invoice 

private 

def check_for_invoice 
    unless invoice.nil? 
    self.errors[:base] << "Cannot delete shipment while its invoice exists." 
    end 
end 

Ale ja po prostu dostać żółtą wiadomość mówiąc: „Przesyłka nie może być usunięty”, ale to było w rzeczywistości usunięte.

Jak mogę zapobiec usunięciu przesyłki?

Odpowiedz

23

before_destroy zwrotna potrzebuje true/false wartości w celu określenia, czy proceeed.

Dodaj return false do check_for_invoice tak:

has_one :invoice 
before_destroy :check_for_invoice 

private 

def check_for_invoice 
    unless invoice.nil?  
    self.errors[:base] << "Cannot delete shipment while its invoice exists." 
    return false 
    end 
end 
+0

Ach tak! Zapomniałem zwrócić false. Też zaksięgowałem tę część kodu błędnie "if invoice.nil?", Zamiast tego powinno to być 'until invoice.nil?'. – leonel

+0

Byłem ciekawy logiki - ale pomyślałem, że to może być coś dziwnego, co robisz. Zaktualizuję moją odpowiedź, aby była zgodna ze względu na potomność. –

+0

Sprawdź [tę odpowiedź na podobne pytanie] (http://stackoverflow.com/a/10257516/703233), aby uzyskać lepszy sposób na zrobienie tego. – nitsas

3

Z docs:

Jeśli before_ * zwrotna zwraca false, wszystkie późniejsze wywołania zwrotne i związane z nimi działania są anulowane.

Więc spróbuj tego:

self.errors[:base] << "Cannot delete shipment while its invoice exists." and return false 
+0

@Jordan masz rację, że 'return' nie jest głównie idiomatyczne w Ruby, ale co, jeśli linia nie jest ostatni w metodzie (plus rozważyć refaktoryzację)? A co, jeśli później dodasz inne instrukcje do metody i zapomnisz dodać zwrot? Myślę, że to są powody, dla których widzisz 'i zwracasz fałsz' użyte w projektach szyn ... – maprihoda

+0

W porządku, to wystarczająco przekonujący argument. Zwróciłem moją wersję. –

4

moje 2 centy w shipment.rb

has_one :invoice, dependent: :restrict 

myślę, że to będzie działać, widziałem to rozwiązanie w innym wątku. Próbuję teraz w moich modelach.

1

dla szyn 4:

class Shipment < ActiveRecord::Base 
    has_one :invoice, dependent: :restrict_with_error 

rade. Jeśli chcesz uzyskać wyjątek zamiast błędu, użyj :restrict_with_exception. Zobacz więcej na the relevant api docs page.

dla szyn 3 (może wcześniej też) spróbować:

class Shipment < ActiveRecord::Base 
    has_one :invoice, dependent: :restrict 
Powiązane problemy