2010-05-14 5 views
40

, 그것은 가능 변경 위의 예는 간단하지만 현재 작업하고있는 프로젝트에서 정말 도움이되기 때문에 묻습니다.기본값을 변경하는 라우팅 레일에서 id 매개 변수 레일에 3의 새로운 라우팅 시스템을 루비를 사용하여

이 매개 변수를 변경할 수 있습니까? 그렇지 않은 경우 이유는 무엇입니까?

+3

"사용자/개체/등을 가져 오는 데 사용되는 기본 ID를 어떻게 변경합니까?"라는 관점에서이 질문을 좋아합니다. " 그러나 기본 ID가 데이터베이스에서 직접 기본 키인 경향이 있으므로 해당 값을 노출시키지 않아야하는 모든 종류의 보안 이유가 있습니다 (SQL 주입 공격 완화, 추측 할 수있는 ID 다른 사용자의 경우 ...). 특히, 사용자 이름을 사용하면 계정에 직접 공격 (pwd guessing)이 가능합니다. 크고 무작위의 고유 한 값을 사용하면이 모든 것이 훨씬 어려워집니다. 건배. –

+0

* 수락 된 답변을 읽은 다음에 대답을 확인하십시오. * – blnc

답변

34

정확하게 이해한다면 원하는 내용은 id이 아니라 username이됩니다.

모델에서 to_param 메서드를 재정 의하여 구현할 수 있습니다. here에 대한 자세한 정보를 얻을 수 있습니다.

+0

이것이 지금은이 문제를 해결할 수있는 유일한 방법입니다. 그래도 원형 교차로 같아. – joeellis

+1

이 포인터 주셔서 감사합니다, 내 문제를 완전히 해결했습니다. 나는이 b/c를 바꿀 수있는 방안을 찾기 위해 이곳에 왔습니다. 정책에 따라 웹에서 기본 키 ID를 보안 문제로 가져 오는 것을 고려합니다. 대신 객체에 큰 임의의 고유 값 (SecureRandom.urlsafe_base64 (15))을 추가하고 to_param에서 반환 된 ID와 RESTful API find_by_OID를 사용합니다. 아마도 루비/레일을 더 잘 이해할 때, 이것은 보석으로 만들 수 있습니다. –

0

사용자 이름을 경로 도우미의 입력으로 전달하십시오. 보기 코드에서

: 컨트롤러에서

user_path(u.username) #/users/john 

usernameid받은 치료 :

def show 
    user = User.find_by_username!(params[:id]) 
    ... 
end 
+0

그게 내가 한 일종의 일이지만, 나는 코드에서 User.find_by_username (params [: username])과 같은 일을하는 것이 더 간단 할 것이라고 생각한다. 정말 레일즈가 이것을 일반적으로 허용하지 않는 이유가 궁금합니다. 아마도 일부 REST 원칙에 위배되는 것일까? – joeellis

1

대답이 아스 커에 의해 허용되었지만,하지만 간단한 방법은 거기에있다 이 작업을 수행. 이 코드를 컨트롤러에 작성하십시오.

authorize_resource :find_by => :username 

및보기에서 링크를 표시하려는 위치에이 코드를 작성하십시오.

<%= link_to "Username", user_path(u.username) %> 

경로 나 컨트롤러에는 다른 변경 사항이 필요하지 않습니다.

업데이트 : 이것은 CanCan gem을 사용하는 경우에만 작동합니다.

+0

CanCan 메서드 인 것 같습니다. 그것은 레일 API에 전혀 언급되어 있지 않습니다. [apidock.com] (http://apidock.com/rails/search?query=authorize_resource) [api.rubyonrails.org] (http://api.rubyonrails.org/?q=authorize_resource) – Nultyi

+0

예, 그렇습니다. CanCan 메서드. 나는 그 대답을 잊어 버렸다. 답변을 업데이트했습니다. – KULKING

1

FriendlyId 보석을 사용하면 도움이됩니다. Ryan Bates는이 보석 사용에 좋은 video tutorial을 가지고 있습니다. 경로에서

61

당신은 레일 4.1에 루비를 들어

resources :user, param: :username 
+4

이것은 받아 들여진 대답이어야한다. 나는'to_param' 메쏘드를 덮어 쓰는 것보다 경로에 인자를 더하는 것이 더 편하다. – omnikron

+1

@omnikron 그것은 당신이 당신의 앱에서 무엇을 얻고 자하는지에 달려있다. 때때로 둘 다 할 필요가있다. (예를 들어,'user_path @ user.username'을 할 필요가 없도록 자원을 라우팅 헬퍼'user_path @ user'에게 직접 전달하고 싶을 때) ... 그렇지만 네가 맞다. 라우팅 기능을 원합니다. – equivalent8

+3

이것은 Rails 4+에서만 작동합니다 –

23

를 사용할 수 있습니다.4 (및 이전 버전) 당신은 모두j..Ujjwal이 무엇을 제안 할 필요가 :

1) config/routes.rb에서 추가, :

resources :user, param: :username 

2) app/models/user.rb에서 추가, :

def to_param 
    username 
end 

# 1 만하면 모든 경로가 올바르게 표시됩니다 (rake routes :

).
$ rake routes 
    Prefix Verb URI Pattern     Controller#Action 
user_index GET /user(.:format)    user#index 
      POST /user(.:format)    user#create 
    new_user GET /user/new(.:format)   user#new 
edit_user GET /user/:username/edit(.:format) user#edit 
     user GET /user/:username(.:format)  user#show 
      PATCH /user/:username(.:format)  user#update 
      PUT /user/:username(.:format)  user#update 
      DELETE /user/:username(.:format)  user#destroy 

그러나 User 인스턴스를 기반으로하는 URL을 구성하는 도우미 메서드는 여전히 URL에 id을 포함합니다. /user/1. 구성된 URL에 username을 얻으려면 # 2처럼 to_param을 무시해야합니다.

+4

2)이 질문이 나타나면 대부분의 시간을 놓친다. 이것은 받아 들여진 응답이어야합니다 – Ben

+0

** **'rails 5.0.2' ** 및 **'ruby 2.4.1'과 함께 작동합니다. – blnc

관련 문제