2011-09-08 5 views
12

레일스 3에서 "알 수없는 작업"오류 및 개발 중 404.html 오류를 표시하고 싶습니다. 내처리기를 내 ApplicationController (및 경우에 따라서는 실제 컨트롤러)에 넣으려고했는데 여전히 추한 오류가 표시됩니다.레일 3에서 사용자 정의 404에 대한 알 수없는 작업 캐치

나는 404에 사용자 지정 항목이 있으며 일반 .html 파일이 될 수 없습니다.

내 경로 :

match '/user/:id/:action', controller: 'users' 

의 URL 내가 접근 해요 : /user/elado/xxx

rescue_from 코드 :

rescue_from AbstractController::ActionNotFound, :with => :action_not_found 

def action_not_found 
    render text: "action_not_found" 
end 

브라우저에서 오류 :

Unknown action 

The action 'xxx' could not be found for UsersController 

그리고 콘솔 :

Started GET "/user/elado/xxx" for 127.0.0.1 at 2011-09-07 19:16:27 -0700 

AbstractController::ActionNotFound (The action 'xxx' could not be found for UsersController): 

rescue_from ActionController::UnknownAction 시도.

제안 사항? 감사합니다.

답변

14

rescue_from 약간 (여전히도 3.1 깨진) 부서졌다. 기본적으로 사용자는 다음을 할 수 없습니다.

rescue_from ActionController::RoutingError 

더 이상 없습니다. here을 참조하십시오.

이 솔루션은 현재 hamiltop이 권장하는 것입니다. "라우팅 오류"경로로가는 모든 경로를 포착하십시오. config \ routes.rb 파일의 마지막에 넣으십시오. 그래서 마지막으로 처리됩니다.

# Any routes that aren't defined above here go to the 404 
match "*a", :to => "application#routing_error" 

def routing_error 
    render "404", :status => 404 
end 

참고 :이 방법은 한 가지 큰 단점이있다. Jammit 또는 Devise와 같은 엔진을 사용하면 catch가 모두 경로를 지정하면 Rails가 엔진의 경로를 무시합니다.

자신의 경로가있는 엔진을 사용하고 있지 않다면 괜찮을 것입니다. 그러나 자체 라우트를 정의하는 엔진을 사용하는 경우 @ arikfr의 대답을 참조하십시오.

+0

다음 링크는 좋은 통찰력을 제공하며 예외 (3.2 이상)를보다 잘 처리하는 방법의 예를 제공합니다. http://geekmonkey.org/articles/29-exception-applications-in-rails-3-2 – Agustin

0

모든 경로를 시도 했습니까? 당신이 사용하는 현재입니다

http://railscasts.com/episodes/46-catch-all-route

와일드 카드 경로는 나쁜 생각 (TM)입니다.

내가 관심있는 경로를 정의한 다음 routes.rb의 마지막 행으로 catchall을 수행하는 것이 좋습니다 (routes.rb에서 처음 정의 된 경로는 나중에 정의됩니다). 그런 다음 원하는 페이지를 렌더링하고 404 상태 코드를 지정할 수 있습니다.

편집 : (이 그것을 사용되지 수있는 것 같아하지만) 당신이 정말로 ... 현재의 접근 방식을 사용하려면

데프 rescue_action (예외) 경우 예외 ActionNotFound, UnknownAction는 # 다음을 처리 할 때 예외 여기 다른 슈퍼 끝 엔드 레일 (3)가 나왔을 때

+0

실제로 다른 경로에 대한 모든 경로를 catch하고 있지만 실제로는 action 대신 실제 사용 가능한 동작 만 추가 할 수 있습니다. 감사. 하지만 나는'rescue_from'을 잘못 사용하고 있습니까? 그것은 작동 해야하는 것 같습니다 ... – elado

+0

감사합니다, 비록'갑부 rescue_action (예외); 사례 예외; ActionController :: UnknownAction, AbstractController :: ActionNotFound가 다음 텍스트를 렌더링 할 때 : "404"; else text : "다른 예외"; 종료; ApplicationController 또는 UsersController의 "end"가 작동하지 않습니다. – elado

9

@Seth Jackson이 제안한 404 오류를 처리하기 위해 catch all route를 사용하면 하나의 큰 단점이 있습니다. Jammit과 같은 자체 경로를 정의하는 레일스 엔진을 사용하면 경로가 무시됩니다.

더 나은 해결책은 404 오류를 잡아낼 랙 미들웨어를 사용하는 것입니다. 내 프로젝트 중 하나에서 이러한 오류를 Hoptoad에보고하는 랙 미들웨어를 구현했습니다. 나는이 구현에 기반을 두었다 : https://github.com/vidibus/vidibus-routing_error이지만 Rails 애플리케이션을 다시 호출하여 404 오류를 처리하는 대신 랙 미들웨어에서 수행하고 nginx가 404 페이지를 표시하도록한다. 당신이 정말로 컨트롤러에 AbstractController::ActionNotFound를 구출하려면

+0

좋은 캐치. 나는 이것을 잊어 버렸다. 나는 다른 엔진 (Devise)에서도 이것을 알아 차렸다. 나는 이것에 대한 대답을 나의 대답에 추가 할 것이다. –

1

, 당신은 이런 식으로 뭔가를 시도 할 수 있습니다 :

class UsersController < ApplicationController 

    private 

    def process(action, *args) 
    super 
    rescue AbstractController::ActionNotFound 
    respond_to do |format| 
     format.html { render :404, status: :not_found } 
     format.all { render nothing: true, status: :not_found } 
    end 
    end 


    public 

    # actions must not be private 

end 

이 (source 참조) AbstractController::ActionNotFound을 제기 AbstractController::Baseprocess 방법을 재정의합니다.

관련 문제