Rails 4 - 将URL从/ user /:id更改为/:username

时间:2016-01-05 03:44:05

标签: ruby-on-rails ruby ruby-on-rails-4 devise

我有一个控制器页面#spamboard,我已将其设置为 routes.rb中的user_root

devise_for :users, controllers: { registrations: 'registrations' }
devise_scope :user do
  get "/signup" => "devise/registrations#new"
  get "/login" => "devise/sessions#new"
  get "/logout" => "devise/sessions#destroy"
  get "/:id" => "users#dashboard", :as => "user_root", :id => :username
end

我希望网址为http://my_app.com/current_user_username

我已将 user.rb 模型中的to_param设置为:

def to_param
  username
end

当我有如下链接时,这可以正常工作:

<%= link_to "MY ACCOUNT", user_root_path(current_user) %>

但在首次登录时,网址为:http://my_app.com/username(明确表示'用户名')而不是http://my_app.com/current_user_username

我尝试将to_param设置为:

def to_param
  "#{username}"
end    

并尝试将 route.rb 设置为:

get "/:id" => "users#dashboard", :as => "user_root", :id => :username, :via => :get

这些都没有解决问题。

环境:Rails 4.2.5,Ruby 2.3.0,Devise gem 3.5.3

非常感谢任何帮助。

4 个答案:

答案 0 :(得分:1)

您只需在routes.rb中的所有内容上添加另一条路径:

get "/:username" => "users#dashboard", :as => "user_root"
devise_for :users, controllers: { registrations: 'registrations' }
devise_scope :user do
  get "/signup" => "devise/registrations#new"
  get "/login" => "devise/sessions#new"
  get "/logout" => "devise/sessions#destroy"
  get "/:id" => "users#dashboard", :as => "user_root", :id => :username
end

然后你需要通过以下方式找到用户:

    @user = User.find_by(username: params[:username])

答案 1 :(得分:1)

只需使用friendly_id

#Gemfile
gem 'friendly_id', '~> 5.1'

$ rails generate friendly_id #-> generates initializer
$ rails generate scaffold user name:string slug:string:uniq #-> adds slug column
$ rake db:migrate

#app/models/user.rb
class User < ActiveRecord::Base
   extend FriendlyId
   friendly_id :username, use: [:slugged, :finders]
end

这样您就可以使用slug / username代替主键:

<%= link_to current_user.username, user_path(current_user) #-> <a href="/users/john_jones" %>

您无需更改控制器代码等即可使用。

-

您的路线可以简化:

#config/routes.rb
resource :user, path: "", only: :show #-> url.com/:id to users#show
devise_for :users, controllers: { registrations: 'registrations' }, path_names: { sign_in: "login", password: "forgot", confirmation: "confirm", unlock: "unblock", sign_up: "", registration: "signup", sign_out: "logout" }

虽然我不知道你是否可以在你的路线中使用current_user(我确信你可以,但我没有经过测试),你可能希望像这样使用/profile:< / p>

resource :profile, controller: :users, only: :show

这会将url.com/profile发送到users#show操作:

#app/controllers/users_controller.rb
class UsersController < ApplicationController
   def show
      current_user...
   end
end

答案 2 :(得分:1)

我通过将此添加到 application_controller.rb

来解决了这个问题
def after_sign_in_path_for(resource)
  user_root_path(current_user)
end

**这是一个特定的答案。

感谢所有花时间回答的人:)

答案 3 :(得分:0)

我遇到了类似的问题,并对路由做了一些更改,但在这里工作是要做的:

    在User.rb模式下
  1. def to_param 用户名 结束

  2. 路线: 资源:users,:path =>'/'做 结束

  3. 控制器 @ user = User.find_by_username(params [:id])

  4. 视图 link_to @ user.username,@ user.username。 避免使用user_path,因为它会将您重定向到www.example.com/users/david 而是跟进我上面已经提到的 它会www.example.com/david比第一个要好。

希望任何人都会得到帮助。