Rails를 사용한 고급 경로 제약

7246 단어 rubyrailswebdev
최근에 약속 링크가 있는 SMS 메시지를 보내는 기능을 작업하고 있었습니다. 결국 링크가 메시지 본문의 대부분을 차지하므로 본문의 공간을 절약하기 위해 링크를 줄이는 몇 가지 옵션을 살펴보고 싶었습니다.
메시지.

Bitly와 같은 것을 사용하는 대신 앱 내에 남아 있는 간단한 옵션이 있는지 확인하고 싶었습니다. 링크 단축 보석에 대한 인터넷 검색을 수행하고 첫 번째 보석 몇 개를 시도했습니다.
그 팝업.

내 링크를 가져 와서 SMS 확인으로 전송되는 단축 버전을 아주 쉽게 만들 수 있었습니다. 몇 가지 테스트 실패를 발견할 때까지 모든 것이 잘 진행되는 것 같았습니다. 내 정적 페이지 중 일부는 404를 반환했습니다. 약간의 파기 후에 나는 /about/contact와 같은 모든 정적 페이지가 쇼트너에 의해 가로채고 있음을 발견했습니다.

ID가 about인 단축 링크를 찾지 못했을 때 404를 반환하고 내 정적 페이지를 손상시켰습니다.

가장 쉬운 해결책은 /srt 와 같은 접두사 아래에 쇼트너 레일 엔진을 장착하는 것입니다.

이것은 내가 끝내었지만 경로 제약 조건을 사용하여 문제를 해결하려고 시도한 것입니다.

경로 제약 조건은 내가 들어 본 적이 있지만 사용할 이유가 없었습니다. 나는 이것이 라우팅 제약 조건을 찌르고 더 많은 경험을 얻을 수 있는 좋은 기회라고 생각했습니다.

경로 제약 조건에는 몇 가지 다른 옵션이 있습니다. 고급 옵션 중 일부는 경로 정의에서 람다를 사용하고 경로 제약 조건에 대해 클래스를 사용하는 조금 더 관련된 옵션입니다.

내 첫 번째 접근 방식은 경로 정의 내에서 람다를 사용하는 것이었지만 결국 클래스를 사용하는 것으로 이동했습니다.

Rails Guides on Advanced Route Constraints

람다 경로 제약 조건 예:

  get '*path', to: 'restricted_list#index',
    constraints: lambda { |request| RestrictedList.retrieve_ips.include?(request.remote_ip) }


클래스 경로 제한 예:

class ShortenerRouteConstraint
  def matches?(request)
    # if request.path is not in static routes it should be a short link
    static_page_routes.exclude?(request.path)
  end

  private

  def static_page_routes
    # dynamically pull all static pages + admin, 404, and errors
    static_page_paths = Dir.new("app/views/static").children.map do |f|
      "/#{File.basename(f, ".html.erb")}"
    end
    static_page_paths << "/admin"
    static_page_paths << "/404"
    static_page_paths << "/500"
  end
end


첫 번째 패스에서는 정적 페이지의 경로를 배열에 추가하고 request.path를 확인하여 요청에 포함되었는지 확인했습니다.

그것은 잘 작동했지만 새 정적 페이지를 추가한 후 404 오류에 대한 또 다른 테스트 실패가 발생했습니다(단축기가 개체를 찾을 수 없을 때 발생함).

일반적으로 사양이 실패하고 무슨 일이 일어나고 있는지 내 기억을 새로 고쳐야 하는 경우, 검사를 동적으로 만들고 수동으로 업데이트하지 않도록 하는 방법이 있는지 알고 싶었습니다.

위의 것과 일치하는 경로 제약 클래스를 만들었습니다. 경로 제약 클래스를 확보한 후 다음 단계는 해당 제약 클래스를 사용하도록 경로를 업데이트하는 것이었습니다.

# config/routes.rb
require 'app/services/ShortenerRouteConstraint.rb'

get "/:id" => "shortener/shortened_urls#show", constraints: ShortenerRouteConstraint.new


참고: 해당 클래스를 넣을 최적의 위치를 ​​정말 몰랐기 때문에 기본적으로 내app/services 디렉토리에 넣고 해당 파일을 내config/routes.rb
보기 파일의 동적 목록에 대해 경로를 확인하는 것은 절대적으로 과잉입니다.
하지만 설정하고 잊는 방법을 찾을 수 있는지 확인하고 싶었습니다.

몇 분 후에 Ruby 문서를 훑어보고 필요한 것을 찾았습니다.

  # dynamically pull all static pages
  static_page_paths = Dir.new("app/views/static").children.map do |f|
    "/#{File.basename(f, ".html.erb")}"
  end


그러면 app/views/static 디렉토리에 대한 새 Dir 개체가 생성됩니다. 우리는 그 자식에 접근하고 map를 사용하여 새
경로 제약 조건에 대한 경로와 일치하는 형식의 배열입니다.

이것은 .html.erb 디렉토리에서 부분을 포함하여 app/views/static 로 끝나는 모든 보기의 이름을 가져옵니다.

출력은 다음과 같습니다.

["/index",
 "/contact",
 "/success",
 "/privacy",
 "/pricing",
 "/about",
 "/terms"]


정적 디렉토리의 모든 페이지를 확인한 후 충돌이 발생한 정적 페이지 외부의 다른 경로에 대한 제약 조건에 /admin , /404/500 를 추가합니다.

이제 정적 컨트롤러에 새 페이지를 추가할 때마다 해당 경로는 단축된 경로에 대해 확인하지 않아야 하는 정적 페이지의 화이트리스트에 추가됩니다.

이전에 언급한 것처럼 결국 다른 경로를 선택하게 되었지만(내가 그곳에서 무엇을 했는지 보셨습니까?) 재미를 위해 솔루션을 과도하게 엔지니어링하는 좋은 연습이라고 생각했습니다.

좋은 웹페이지 즐겨찾기