2009-07-13 4 views
0

리소스의 ID로 텍스트 퍼머 링크를 사용하는 Rails 앱의 경로에 대한 RESTful 설정이 있습니다.Ruby on Rails에서 새로운 리소스를 생성 할 때 라우팅 오버랩 없음을 확인하십시오.

는 또한뿐만 아니라 명명 된 자원 예와 중복되는 몇 가지 특별한 이름이 경로가 있습니다 :

# bunch of special URLs for one off views to be exposed, not RESTful 
map.connect '/products/specials', :controller => 'products', :action => 'specials' 
map.connect '/products/new-in-stock', :controller => 'products', :action => 'new_in_stock' 

# the real resource where the products are exposed at 
map.resources :products 

Product 모델은 이름에 따라 영구 링크를 생성하는 permalink_fu을 사용하고, ProductsController은 조회를 수행 액세스 할 때 permalink 필드에. 그건 모두 잘 작동합니다.

데이터베이스에 새로운 Product 레코드를 만들 때 생성 된 퍼가 링크가 이 아니고이 특수 URL과 중첩되는지 확인하고자합니다. 사용자가 specials 또는 new-in-stock 또는 new 또는 edit 같은 심지어 일반 레일 편안하고 자원의 방법이라는 제품을 만들려고하면

, 나는, 컨트롤러, 라우팅 구성을 조회 모델 객체에 오류를 설정할 대한 검증 실패 새 기록을 남기고 저장하지 마십시오.

알려진 불법 퍼머 링크 이름의 목록을 하드 코딩 할 수는 있지만 그렇게하는 것이 더러워 보입니다. 나는 그것을 자동으로하기 위해 라우팅에 연결하고 싶다.

답변

1

음,이 작품 (컨트롤러와 모델 이름이 무죄를 보호하고 쉽게, 실제 설정이 예보다 더 복잡 대답 할 수 있도록 변경),하지만 난 그것이 얼마나 꽤 잘 모르겠어요 . 주요 문제는 컨트롤러/라우팅 로직을 모델에 섞는 것입니다. 기본적으로 모델에 사용자 정의 유효성 검사를 추가하여 검사 할 수 있습니다. 이 방법은 문서화되지 않은 라우팅 방법을 사용하므로 앞으로 어떻게 안정 될지 확신 할 수 없습니다. 누구든지 더 좋은 아이디어를 얻었습니까?

class Product < ActiveRecord::Base 
    #... other logic and stuff here... 

    validate :generated_permalink_is_not_reserved 

    def generated_permalink_is_not_reserved 
    create_unique_permalink # permalink_fu method to set up permalink 
    #TODO feels really ugly having controller/routing logic in the model. Maybe extract this out and inject it somehow so the model doesn't depend on routing 
    unless ActionController::Routing::Routes.recognize_path("/products/#{permalink}", :method => :get) == {:controller => 'products', :id => permalink, :action => 'show'} 
     errors.add(:name, "is reserved") 
    end 
    end 
end 
+0

이것은 이동하는 방법처럼 보이지만 모델에서 라우팅/컨트롤러 로직을 가지고 있고 그것을 분리하려고하는 것에 대해 걱정하지 않아도됩니다. 실제로 시스템에서 모델 *은 라우팅에 의존합니다. 다른 모델과 충돌하는 모델은 유효하지 않습니다. – ideasasylum

0

그렇지 않은 경로는 사용할 수 있습니다. 누군가가 제목에 대한 예약어를 선택했는지 여부에 관계없이 이런 식으로는 아무런 차이가 없습니다.

map.product_view '/product_view/:permalink', :controller => 'products', :action => 'view' 

그리고 귀하의 의견에

는 :

product_view_path(:permalink => @product.permalink) 
+0

불행히도이 경우 옵션이 아닙니다. URL은 이미 설정되어 있으며 관련 SEO 값과 기타 시스템 구성에 따라 달라 지므로 쉽게 변경할 수 없습니다. 모든 것이 그대로 작동합니다. 사용자가 중복되는 이름을 만들면 해당 제품이 시스템에서 효과적으로 무시됩니다. – madlep

+0

일반적인 "to_param"예제에서 페이지를 가져 와서 이름 앞에 ID를 추가 할 수도 있습니다. 결국 "01-foo-bar"처럼 보이는 영구 링크가 생깁니다. – jdl

0

그것은이 같은 이유로 명시 적으로 자신 URI를 관리 할 수있는, 그리고 당신이 원하지 않는 경로를 노출하는 실수 피하기 위해 더 좋습니다.