2010-02-25 7 views
33

Użytkownik może edytować tylko swoje własne stanowisko, więc używam następujących czynności, aby sprawdzić, czy użytkownik może wprowadzić formę EDIT:ratunkowy z ActiveRecord :: RecordNotFound w Rails

def edit 
    @post = Load.find(:first, :conditions => { :user_id => session[:user_id], :id => params[:id]}) 
    rescue ActiveRecord::RecordNotFound 
    flash[:notice] = "Wrong post it" 
    redirect_to :action => 'index' 
    end 

Ale to nie działa, każde pomysły, co robię źle?

Odpowiedz

52

Jeśli chcesz użyć instrukcji ratunkowego trzeba użyć find() w taki sposób, że budzi wyjątki, czyli przepuszczenie identyfikator, który chcesz odnaleźć.

def edit 
    @post = Load.scoped_by_user_id(session[:user_id]).find(params[:id]) 
rescue ActiveRecord::RecordNotFound 
    flash[:notice] = "Wrong post it" 
    redirect_to :action => 'index' 
end 
+0

Dziękuję @ Simone Carletti, to jest to. – Adnan

6

Okazuje się, że korzystałeś z funkcji ratowania i znajdź (: pierwszy) niepoprawnie.

find: first zwraca zero, jeśli żaden rekord nie odpowiada warunkom. To nie budzi ActiveRecord :: RecordNotFound

spróbować

def edit 
    @post = Load.find(:first, :conditions => { :user_id => session[:user_id], :id => params[:id]}) 
    if @post.nil? 
    flash[:notice] = "Wrong post it" 
    redirect_to :action => 'index' 
    end 
end 
+0

Dostaję „Powołani id do zera, co błędnie być 4 - jeśli naprawdę chciał id zera, należy object_id” – Adnan

+1

uzywasz ratunkowy źle, ale prawdziwym problemem jest to, że znajdują się: pierwsza zwraca zero, jeśli nie znaleziono rekordu. Rozwiązanie zaktualizowane w celu rozwiązania prawdziwego źródła problemu. – EmFi

+0

@DemitryT: Podczas gdy twój kod dawałby ten sam rezultat. W tym przypadku postanowiłem napisać to w ten sposób, aby wyraźnie rozwiązać problem z pierwotnym pytaniem. Co do preferencji, nie podoba mi się użycie oświadczenia przydziału jako warunku. Uważam, że połączenie trudniejsze do utrzymania i debugowania. – EmFi

34

Można również użyć rescue_from metodę ActionController „s. Aby zrobić to dla całej aplikacji na raz!

class ApplicationController < ActionController::Base 
    rescue_from ActiveRecord::RecordNotFound, :with => :record_not_found 

    def record_not_found 
    render 'record_not_found' # Assuming you have a template named 'record_not_found' 
    end 
end 
+0

Dlaczego potrzebuję "true" na końcu? Ponadto, co chciałbym dołączyć do insted '# ...'? –

+0

@AlexPopov Dobre pytanie, nie pamiętam, dlaczego to opublikowałem. Nie sądzę, że tego potrzebujesz ... –

+1

Również "renderuj" record_not_found'' oznacza, że ​​musisz mieć ten szablon. Alternatywnie możesz użyć 'render text: 'Some descriptive message''. –