[英]How do I make my redirect include the name instead of an ID?
I'm using Rails 5.1. 我正在使用Rails 5.1。 In my controller, I would like to redirect to my "show" method like so 在我的控制器中,我想重定向到我的“show”方法
redirect_to(@organization)
but I would like the URL to appear as 但我希望URL显示为
/organization/organization_name
instead of 代替
/organization/primary_key_id
How do I set this up? 我该如何设置? I already have a field "name" in my Organization model. 我的组织模型中已经有一个字段“name”。
Edit: As requested, this is the index method of my PagesController
... 编辑:根据要求,这是我的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
Edit: My config/routes.rb
file 编辑:我的config/routes.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
Here's the app/model/stratum_worker.rb
file 这是app/model/stratum_worker.rb
文件
class StratumWorker < ApplicationRecord
has_one :organization_worker
has_one :organization, :through => :organization_worker
OK, if you are not interested to use any gem then you can without gem like 好的,如果你对使用任何宝石不感兴趣那么你可以没有宝石之类的
class Model < ApplicationRecord
def to_param # overridden
organization_name
end
end
in this case, you need to make sure the organization_name
name is unique, for uniqueness the organization_name
you can use validation like this 在这种情况下,你需要确保organization_name
名是唯一的,独特的organization_name
您可以使用验证这样
validates_uniqueness_of :organization_name
then the model will look like this 然后模型看起来像这样
class Model < ApplicationRecord
validates_uniqueness_of :organization_name
def to_param # overridden
organization_name
end
end
and now to the controller using find_by_organization_name(params[:organization_name])
instead of find(params[:id])
. 现在使用find_by_organization_name(params[:organization_name])
代替find(params[:id])
到控制器。
Second Option 第二选择
You can not change anything to your controller if used like this in just model 如果在模型中使用这样的话,则无法对控制器进行任何更改
class Model < ApplicationRecord
def to_param # overridden
organization_name
"#{id} #{organization_name}".parameterize
end
end
then the URL looks like this /10-microsoft
. 然后URL看起来像/10-microsoft
。
See this to_param
method. 请参阅此to_param
方法。 The complete reference of with gem or without gem Rails Friendly URLs
带有gem或没有gem Rails Friendly URLs
的完整参考
RailsCasts.com created an episode for Pretty URLs with FriendlyId, can you check it out for getting the idea. RailsCasts.com为PrettyId创建了一个漂亮网址的剧集,你可以看看它是否有想法。
From Comment 来自评论
I don't think what's going on but sure something wrong with the relationship, can you check like this 我不认为发生了什么,但确定这种关系有问题,你能不能这样检查
redirect_to(worker.organizations.first)
#=> OR
redirect_to organization_path(worker.organizations.first.id)
Update 更新
I think worker.organization
are missing somehow, would you try like this? 我认为worker.organization
以某种方式丢失了,你会这样尝试吗?
if worker && worker.organizations.present?
redirect_to(worker.organizations.first)
....
the present
method making sure worker.organizations
not blank. 在present
方法确保worker.organizations
不是空白。
I don't know about the relationship, you can try like this and let me know what's happening if it's not working then I strongly recommend to post the models with relationship concept. 我不知道这种关系,你可以尝试这样,让我知道发生了什么,如果它没有工作,那么我强烈建议发布关系概念的模型。
Update 2 after question update 问题更新后更新2
At first, you don't need the through
relationship because it uses too Many To Many
relationships. 首先,您不需要through
关系,因为它使用了太多Many To Many
关系。 Your relationship is One To One
then your model will look like this 您的关系是One To One
那么您的模型将如下所示
class StratumWorker < ApplicationRecord
has_one :organization_worker
....
has_one :organization, :through => :organization_worker has_one:organization,:through =>:organization_worker
organization_worker.rb
file like this 像这样的organization_worker.rb
文件
class OrganizationWorker < ApplicationRecord
belongs_to :stratum_worker
#=> Add code what you need like for URL which was the actual motive in this post
....
Then the action looks like this 然后动作看起来像这样
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
and the show action 和节目动作
OrganizationWorker.find(params:id)
I think the problem will solve now. 我认为现在问题会解决。 If still, you getting errors then please read the One To One
relationship again & again until clearing the relationship concept. 如果仍然存在错误,那么请再次阅读One To One
关系,直到清除关系概念。
Hope it will help. 希望它会有所帮助。
Method that is called under the hood for id generation is to_param
在id生成的引擎盖下调用的方法是to_param
so in your case to get your desired result you should add this to your Organization
class: 因此,在您的情况下,要获得所需的结果,您应该将其添加到您的Organization
类:
class Organization < ApplicationRecord
...
def to_param
name
end
...
end
!!!WARNING!!! !!!警告!!! - since Rails is also using the parameter on the other side (eg in show method Organization.find(params[:id])
uses the URL id), now it will be params[:id] == "some_organization_name"
so change your instance lookups accordingly - in show
action for example use Organization.find_by!(name: params[:id])
and so on - 因为Rails也在另一边使用参数(例如在show方法中, Organization.find(params[:id])
使用URL id),现在它将是params[:id] == "some_organization_name"
所以改变你的实例查找相应 - 例如在show
动作中使用Organization.find_by!(name: params[:id])
等等
As for your routing error - make sure that worker.organization
is not nil
. 至于你的路由错误 - 确保worker.organization
不是nil
。
There is a gem friendly_id that does exactly what you are asking for: https://github.com/norman/friendly_id 有一个gem friendly_id完全符合您的要求: https : //github.com/norman/friendly_id
You add, 你添加,
gem 'friendly_id'
Then bundle install
and run rails generate friendly_id
and rails db:migrate
然后bundle install
和run rails generate friendly_id
和rails db:migrate
to your Gemfile and, 到您的Gemfile和,
class Organization < ApplicationRecord
extend FriendlyId
friendly_id :name, use: :slugged
end
to your model then, 那么你的模型,
class OrganizationController < ApplicationController
def show
@user = Organization.friendly.find(params[:id])
end
end
to your controller. 到您的控制器。
This prevents the issues you can run into in Kkulikovskis answer where you have to make sure that you are looking things up correctly. 这可以防止你在Kkulikovskis中遇到的问题回答,你必须确保你正确地查找事情。
I wrote a post here detailing exactly this a while ago. 我在这里写了一篇文章,详细介绍了这个问题。 Most of my answer will be from there. 我的大部分答案都是从那里开始的。 The relevant Rails documentation for this is here . 相关的Rails文档就在这里 。
Quick definitions: 快速定义:
organization_name
Slug:用于标识记录的URL的一部分,在您的情况下为organization_name
id
. 这通常是并且应该是id
。 If you type organization_path(@organization)
, it'll automatically use the id
attribute in the URL. 如果键入organization_path(@organization)
,它将自动使用URL中的id
属性。 To adjust to using organization_name
, you'll need to make 2 changes: 要调整为使用organization_name
,您需要进行2次更改:
routes.rb
file. 覆盖routes.rb
文件中的路径参数。 to_param
method in the model 覆盖模型中的to_param
方法 At the moment, if you run rails routes
your routes look like so: 目前,如果您运行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
The edit_organization
and organization
paths use id
as a parameter to lookup your organization. edit_organization
和organization
路径使用id
作为查询组织的参数。
Use this to override the route params 用它来覆盖路线参数
Rails.application.routes.draw do
resources :organizations, param: :organization_name
end
Now rails routes
will show that your routes look like so: 现在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/: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
By default organization.to_param
will return the id
of the organization. 默认情况下, organization.to_param
将返回organization.to_param
的id
。 This needs to be overridden, do this by modifying your Model: 这需要被覆盖,通过修改模型来执行此操作:
class Organization < ApplicationRecord
def to_param
organization_name
end
end
You can now continue using your redirects and forms as usual, but instead of the route using the id
, it'll now use the organization name. 您现在可以像往常一样继续使用重定向和表单,但现在使用组织名称而不是使用id
的路由。
Also, good luck with your mining pool! 还有,祝你的采矿池好运! Lemme know which coin you're mining and I might join! Lemme知道你正在挖掘哪枚硬币,我可能会加入!
Also, I didn't cover this because it isn't a part of your original question, but, you should ensure that the organization_name
is unique! 此外,我没有介绍这个,因为它不是原始问题的一部分,但是,您应该确保organization_name
是唯一的! Not only should you add a uniqueness constraint validates :organization_name, uniqueness: true
in the mode, you should also enforce it at the database level in your migration. 您不仅应该在模式中添加唯一性约束validates :organization_name, uniqueness: true
,还应该在迁移中在数据库级别强制执行它。
When your routes are defined as so: 当您的路线定义如下:
resources :organizations, :only => [:show] do
post 'update_work'
get 'get_work'
get 'mine'
get 'poll'
post 'submit'
get 'home'
get 'terms_of_use'
end
Your routes will be as so: 您的路线将如下:
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
Changing the param
like so: 像这样改变param
:
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
Will change your routes to 将您的路线改为
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
Which should work totally fine with your redirect. 哪个应该与您的重定向完全一致。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.