我让我的rails应用程序运行OmniAuth-identity,以“用户”模式保存用户。 访问用户需要指向:
0.0.0.0:3000/users/:id
但我想通过输入用户的唯一名称(例如facebook或twitter)来实现目标:
0.0.0.0:3000/username
所以我创造了一条全球化的路线:
match "/*id" => "users#show"
并修改用户控制器show方法,按名称而不是ID查找,具体取决于传递的参数:
def show
if params[:id].is_a?(String)
@user = User.find_by_name(params[:id])
else
@user = User.find(params[:id])
end
respond_to do |format|
format.html # show.html.erb
format.json { render json: @user }
end
end
路由工作,如果我去
0.0.0.0:3000/username
它成功显示了用户信息。 但是注销或找到像旧路由这样的用户是不行的..(即使条件我添加到控制器检查String || Int。
当我做这件事时,我得到了:
NoMethodError in Users#show
Showing /home/juanchi/Dropbox/GitHub/RSandBox/app/views/users/show.html.erb where line #5 raised:
undefined method `provider' for nil:NilClass
Extracted source (around line #5):
2:
3: <p>
4: <b>Provider:</b>
5: <%= @user.provider %>
6: </p>
7:
8: <p>
Rails.root: /home/juanchi/Dropbox/GitHub/RSandBox
Application Trace | Framework Trace | Full Trace
app/views/users/show.html.erb:5:in `_app_views_users_show_html_erb___448583227_80374500'
app/controllers/users_controller.rb:22:in `show'
Request
Parameters:
{"id"=>"logout"}
Show session dump
Show env dump
Response
Headers:
None
无法在用户控制器的show方法获取信息。但是当使用新路线时,它很好......那么它缺少什么?
如何同时支持我的新路由规则和旧路由规则?
该路由与用户登录方法有什么关系?
注销时调用会话#detroy方法:
def destroy
session[:user_id] = nil
redirect_to root_url, :notice => "Goodbye!"
end
答案 0 :(得分:1)
我不确定我是否有这个想法,但我认为你不需要使用全球路线。
您可以使用以下内容:
get "users/:id" => "users#show"
get ":username" => "users#show"
在您的操作中,您可以检查参数是否存在:
def show
if params[:id].present?
@user = User.find(params[:id])
elsif params[:username].present?
@user = User.find_by_name(params[:username])
end
end
要在代码中检查参数的类型没有意义,因为它总是String(如果它是nil,则为NilClass)。
还有一个重要的事情 - 路由是有序的,所以你必须在路由表末尾的某个地方放置get ":username" ...
,以防止与/ logout,/ login等标准操作发生冲突。
实际上,完全消除这些冲突并不简单 - 假设您有用户选择名称“注销”。因此,您必须添加另一个阻止用户使用此类名称的逻辑。
更新:我忘了解释为什么我认为没有必要使用globbing - 你需要使用globbing来捕捉“foo / bar”,“something / nice / in / rails”之类的内容match "*xxx"