Ruby on rails 如何使重定向包含名称而不是ID?

Ruby on rails 如何使重定向包含名称而不是ID?,ruby-on-rails,redirect,configuration,routes,Ruby On Rails,Redirect,Configuration,Routes,我使用的是Rails 5.1。在我的控制器中,我想重定向到我的“show”方法,如下所示 redirect_to(@organization) 但是我希望URL显示为 /organization/organization_name 而不是 /organization/primary_key_id 我该如何设置?我的组织模型中已经有一个字段“name” 编辑:根据要求,这是我的PagesController的索引方法 class PagesController < Applicatio

我使用的是Rails 5.1。在我的控制器中,我想重定向到我的“show”方法,如下所示

redirect_to(@organization)
但是我希望URL显示为

/organization/organization_name
而不是

/organization/primary_key_id
我该如何设置?我的组织模型中已经有一个字段“name”

编辑:根据要求,这是我的
PagesController
的索引方法

class PagesController < ApplicationController

  # Should be the home page
  def index
    worker_id = params[:worker_id]
    worker = Worker.find_by_id(worker_id)
    if worker && worker.organization
      redirect_to(worker.organization)
    else
      render :file => "#{Rails.root}/public/404", layout: false, status: 404
    end
  end

end
这是
app/model/strateum\u worker.rb
文件

  resources :organizations, :only => [:show] do
    post :update_work
    get :get_work
    get :mine
    get :poll
    post :submit
    get :home
    get :terms_of_use
  end
class StratumWorker < ApplicationRecord

  has_one :organization_worker
  has_one :organization, :through => :organization_worker
class StratumWorker:organization\u worker

在引擎盖下调用以生成id的方法是
to_param

因此,在您的情况下,为了获得所需的结果,您应该将其添加到您的
组织中
类:

class Organization < ApplicationRecord
  ...

  def to_param
    name
  end

  ...
end
班级组织
!!!警告-由于Rails也在另一端使用参数(例如,在show method
Organization.find(params[:id])
中使用URL id),现在它将是
params[:id]=“some\u Organization\u name”
所以相应地更改实例查找-在
show
操作中,例如,使用
Organization.find\u by!(名称:params[:id])
等等


至于路由错误,请确保
worker.organization
不是
nil

有一个gem-friendly_-id,它完全符合您的要求:

你加上

gem 'friendly_id'
然后安装
bundle
并运行
rails生成友好的\u id
rails db:migrate

到你的档案和

class Organization < ApplicationRecord
  extend FriendlyId
  friendly_id :name, use: :slugged
end
班级组织
那你的模特呢,

class OrganizationController < ApplicationController
  def show
    @user = Organization.friendly.find(params[:id])
  end
end
class OrganizationController
到你的控制器


这可以防止在Kkulikovski的答案中遇到问题,您必须确保正确查找内容。

好的,如果您不想使用任何gem,那么您可以不使用gem-like

class Model < ApplicationRecord
   def to_param  # overridden
      organization_name
    end
end
然后模型会像这样

validates_uniqueness_of :organization_name
class Model < ApplicationRecord
    validates_uniqueness_of :organization_name

    def to_param  # overridden
      organization_name
    end
end
class OrganizationWorker < ApplicationRecord

    belongs_to :stratum_worker 

    #=> Add code what you need like for URL which was the actual motive in this post
....
def index
    worker_id = params[:worker_id]
    worker = StratumWorker.find_by_id(worker_id)
    if worker && worker.organization_worker.present?
      #redirect_to(worker.organization_worker)
      redirect_to organization_path(worker.organization_worker)
    else
      render :file => "#{Rails.root}/public/404", layout: false, status: 404
    end
end
然后URL看起来像microsoft的
/10

看看这个方法。有无宝石的完整参考

用FriendlyId为漂亮的URL创建了一个插曲,你能帮我看看吗

来自评论


我不认为发生了什么,但肯定是关系出了问题,你能这样检查一下吗

redirect_to(worker.organizations.first)
#=> OR
redirect_to organization_path(worker.organizations.first.id)
class StratumWorker < ApplicationRecord

    has_one :organization_worker
....
更新

我想
工人.组织
不知怎么找不到了,你能这样试试吗

if worker && worker.organizations.present?
   redirect_to(worker.organizations.first)
....
present
方法确保
worker.organizations
不为空

我不知道这种关系,你可以这样尝试,如果它不起作用,让我知道发生了什么,然后我强烈建议发布带有关系概念的模型

问题更新后更新2

首先,您不需要通过
关系,因为它使用了太多的关系。你的关系是这样的,那么你的模型就是这样的

redirect_to(worker.organizations.first)
#=> OR
redirect_to organization_path(worker.organizations.first.id)
class StratumWorker < ApplicationRecord

    has_one :organization_worker
....
然后动作看起来像这样

validates_uniqueness_of :organization_name
class Model < ApplicationRecord
    validates_uniqueness_of :organization_name

    def to_param  # overridden
      organization_name
    end
end
class OrganizationWorker < ApplicationRecord

    belongs_to :stratum_worker 

    #=> Add code what you need like for URL which was the actual motive in this post
....
def index
    worker_id = params[:worker_id]
    worker = StratumWorker.find_by_id(worker_id)
    if worker && worker.organization_worker.present?
      #redirect_to(worker.organization_worker)
      redirect_to organization_path(worker.organization_worker)
    else
      render :file => "#{Rails.root}/public/404", layout: false, status: 404
    end
end
还有表演

OrganizationWorker.find(params:id)
我想问题现在会解决的。如果仍然存在错误,请再次阅读关系,直到清除关系概念

希望能有所帮助。

我不久前写了一篇文章详细介绍了这一点。我的大部分答案都将来自那里。这方面的相关Rails文档如下所示

快速定义:

  • Slug:URL的一部分,用于识别记录,在您的案例中是
    organization\u name
  • 主键:数据库记录的唯一标识符。这通常是并且应该是
    id
总结 如果键入
organization\u path(@organization)
,它将自动使用URL中的
id
属性。要调整为使用
组织名称
,您需要进行两项更改:

  • 覆盖
    routes.rb文件中的route参数
  • 在模型中重写
    to_param
    方法
  • 1.覆盖路由参数 目前,如果您运行
    rails routes
    您的路线看起来是这样的:

    organizations       GET    /organizations(.:format)                     organizations#index
                        POST   /organizations(.:format)                     organizations#create
    new_organization    GET    /organizations/new(.:format)                 organizations#new
    edit_organization   GET    /organizations/:id/edit(.:format)            organizations#edit
    organization        GET    /organizations/:id(.:format)                 organizations#show
                        PATCH  /organizations/:id(.:format)                 organizations#update
                        PUT    /organizations/:id(.:format)                 organizations#update
                        DELETE /organizations/:id(.:format)                 organizations#destroy
    
    organizations       GET    /organizations(.:format)                                    organizations#index
                        POST   /organizations(.:format)                                    organizations#create
    new_organization    GET    /organizations/new(.:format)                                organizations#new
    edit_organization   GET    /organizations/:organization_name/edit(.:format)            organizations#edit
    organization        GET    /organizations/:organization_name(.:format)                 organizations#show
                        PATCH  /organizations/:organization_name(.:format)                 organizations#update
                        PUT    /organizations/:organization_name(.:format)                 organizations#update
                        DELETE /organizations/:organization_name(.:format)                 organizations#destroy
    
    edit_organization
    organization
    路径使用
    id
    作为参数来查找您的组织

    使用此选项可覆盖管线参数

    Rails.application.routes.draw do
      resources :organizations, param: :organization_name
    end
    
    现在
    rails-routes
    将显示您的路线如下所示:

    organizations       GET    /organizations(.:format)                     organizations#index
                        POST   /organizations(.:format)                     organizations#create
    new_organization    GET    /organizations/new(.:format)                 organizations#new
    edit_organization   GET    /organizations/:id/edit(.:format)            organizations#edit
    organization        GET    /organizations/:id(.:format)                 organizations#show
                        PATCH  /organizations/:id(.:format)                 organizations#update
                        PUT    /organizations/:id(.:format)                 organizations#update
                        DELETE /organizations/:id(.:format)                 organizations#destroy
    
    organizations       GET    /organizations(.:format)                                    organizations#index
                        POST   /organizations(.:format)                                    organizations#create
    new_organization    GET    /organizations/new(.:format)                                organizations#new
    edit_organization   GET    /organizations/:organization_name/edit(.:format)            organizations#edit
    organization        GET    /organizations/:organization_name(.:format)                 organizations#show
                        PATCH  /organizations/:organization_name(.:format)                 organizations#update
                        PUT    /organizations/:organization_name(.:format)                 organizations#update
                        DELETE /organizations/:organization_name(.:format)                 organizations#destroy
    
    2.覆盖模型参数 默认情况下,
    organization.to_param
    将返回组织的
    id
    。这需要重写,请通过修改模型来执行此操作:

    class Organization < ApplicationRecord
      def to_param
        organization_name
      end
    end
    
    您的路线如下:

     organization_update_work POST   /organizations/:organization_id/update_work(.:format)                                    organizations#update_work
        organization_get_work GET    /organizations/:organization_id/get_work(.:format)                                       organizations#get_work
            organization_mine GET    /organizations/:organization_id/mine(.:format)                                           organizations#mine
            organization_poll GET    /organizations/:organization_id/poll(.:format)                                           organizations#poll
          organization_submit POST   /organizations/:organization_id/submit(.:format)                                         organizations#submit
            organization_home GET    /organizations/:organization_id/home(.:format)                                           organizations#home
    organization_terms_of_use GET    /organizations/:organization_id/terms_of_use(.:format)                                   organizations#terms_of_use
                 organization GET    /organizations/:id(.:format)                                                             organizations#show
    
    更改
    参数
    ,如下所示:

      resources :organizations, :only => [:show], param: :organization_name do
        post  'update_work'
        get   'get_work'
        get   'mine'
        get   'poll'
        post  'submit'
        get   'home'
        get   'terms_of_use'
      end
    
    将更改您的路线到

     organization_update_work POST   /organizations/:organization_organization_name/update_work(.:format)                     organizations#update_work
        organization_get_work GET    /organizations/:organization_organization_name/get_work(.:format)                        organizations#get_work
            organization_mine GET    /organizations/:organization_organization_name/mine(.:format)                            organizations#mine
            organization_poll GET    /organizations/:organization_organization_name/poll(.:format)                            organizations#poll
          organization_submit POST   /organizations/:organization_organization_name/submit(.:format)                          organizations#submit
            organization_home GET    /organizations/:organization_organization_name/home(.:format)                            organizations#home
    organization_terms_of_use GET    /organizations/:organization_organization_name/terms_of_use(.:format)                    organizations#terms_of_use
                 organization GET    /organizations/:organization_name(.:format)                                              organizations#show
    

    这对你的重定向应该很好

    您可以使用gemYa,该答案与您的设置不匹配。您可能还想共享
    PagesController
    代码。能否在其中包含OrganizationsController和show方法?我怀疑这就是您的
    缺少所需密钥:[:id]
    的原因。这不是来自路由吗?我的意思是,错误表明它甚至没有在控制器中执行任何代码,因为它不知道如何调用正确的方法。也许我错了。如果这确实是问题所在,我的路线将在问题中公布。您是否尝试过为(工人组织)添加
    放置url\u
    ,并看到它正在生成您所期望的内容?您还需要对
    名称
    设置唯一性约束,并且根据
    名称
    中允许的内容,您可能希望在路由上添加一个
    :约束
    ,以避免与格式等混淆。@Kkulikovskis,thx,但我仍然使用它