4

私の User モデルには通常のid主キーがありますloginが、識別子として使用できる一意のものもあります。したがって、ユーザーが ID またはログインによってアクセスできるようにルートを定義したいと思います。理想的には、ルートは次のようになります。

/users/:id (GET) => show (:id)
/users/:id (PUT) => update (:id)
...

/users/login/:login (GET) => show (:login)
/users/login/:login (PUT) => update (:login)
...

これを行うための最良の方法は何ですか (または同様のもの)?

4

4 に答える 4

1

実際、カイルブーンはここで正しい考えを持っています。しかし、それは少しずれています。params変数が入ると、すべての値が文字列として格納されるため、彼の例では毎回falseが返されます。あなたができることはこれです:

if params[:id].to_i.zero?
@user = User.find_by_login params[:id]
else
@user = User.find params[:id]
end

このように、:idが実際の文字列である場合、Rubyはそれを0に変換します。ruby-debuggemを使用してparamsハッシュを確認することで、これをテストできます。

(コメントしたばかりですが、まだ十分な経験がありません;)

于 2009-03-03T02:47:49.827 に答える
1

コントローラ メソッドに渡された ID が整数かどうかを確認するだけです。

if params[:id].is_a?(Integer)
    @user = User.find params[:id]
else
    @user = User.find_by_login params[:id]

特別なルートを追加する必要はありません。

于 2009-03-03T02:31:35.403 に答える
1

これまでのところ、私が思いつくことができる最高のものはこれです:

map.resources :users

map.resources :users_by_login,
     :controller => "User",
     :only => [:show, :edit, :update, :destroy],
     :requirements => {:by_login => true}

通常の RESTful ルートがユーザー用に作成され、その上に、users_by_loginリソースは次のルート (およびそれらのみ) を追加します。

GET    /users_by_login/:id/edit
GET    /users_by_login/:id/edit.:format
GET    /users_by_login/:id
GET    /users_by_login/:id.:format
PUT    /users_by_login/:id
PUT    /users_by_login/:id.:format
DELETE /users_by_login/:id
DELETE /users_by_login/:id.:format

これらのルートは実際には にもマッピングされますUserController( show// edit/メソッドのみ)。追加のパラメーターが追加されます ( に等しい): このようにして、メソッドは、パラメーターがログインまたは ID を表しているかどうかを判断できます。updatedestroyby_logintrueUserControllerid

それは仕事をしますが、もっと良い方法があればいいのにと思います。

于 2009-03-03T01:42:36.863 に答える
0

ここで何をしているのか正確にはわかりませんが、これは役立つかもしれません。

:member または :collectionオプションを追加することで、rails が提供する自動 RESTful ルートの外部にあるアクションを定義できます。

map.resources :users, :member => { :login => [:post, :get] }

これにより、次のようなルートが生成されます。

/users/:id (GET)
...
/users/:id/login (GET)
/users/:id/login (POST)

もう 1 つできることは、検索する属性としてログインを使用することです (一意であると仮定します)。Ryan Batesのスクリーンキャストをご覧ください。コントローラーには次のものがあります。

def show
@user = User.find_by_login(params[:id])
...
end

彼はまた、あなたを助けるかもしれない別のスクリーンキャストを持っています. 2 つ目は、カスタムの名前付きルートについて説明しています。

于 2009-03-03T01:32:48.527 に答える