Rails中的全局路由3

时间:2012-09-11 21:41:45

标签: ruby-on-rails omniauth

我让我的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

1 个答案:

答案 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"