我正在使用Rails 5.1。在我的控制器中,我想重定向到我的“show”方法,如此
redirect_to(@organization)
但我希望网址显示为
/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
修改:我的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
这是app/model/stratum_worker.rb
文件
class StratumWorker < ApplicationRecord
has_one :organization_worker
has_one :organization, :through => :organization_worker
答案 0 :(得分:3)
好的,如果你对使用任何宝石不感兴趣,那么你就可以没有宝石了
class Model < ApplicationRecord
def to_param # overridden
organization_name
end
end
在这种情况下,您需要确保organization_name
名称是唯一的,唯一性organization_name
您可以使用此类验证
validates_uniqueness_of :organization_name
然后模型看起来像这样
class Model < ApplicationRecord
validates_uniqueness_of :organization_name
def to_param # overridden
organization_name
end
end
现在使用find_by_organization_name(params[:organization_name])
代替find(params[:id])
来控制器。
第二个选项
如果仅在模型
中使用,则无法对控制器进行任何更改class Model < ApplicationRecord
def to_param # overridden
organization_name
"#{id} #{organization_name}".parameterize
end
end
然后,网址看起来像/10-microsoft
。
请参阅此to_param
方法。使用gem或没有gem Rails Friendly URLs
RailsCasts.com使用FriendlyId创建了一个漂亮网址的剧集,你可以查看它以获得这个想法。
来自评论
我不知道发生了什么,但确定这段关系出了问题,你能不能这样检查
redirect_to(worker.organizations.first)
#=> OR
redirect_to organization_path(worker.organizations.first.id)
<强>更新强>
我认为worker.organization
以某种方式遗失了,你会尝试这样吗?
if worker && worker.organizations.present?
redirect_to(worker.organizations.first)
....
present
方法,确保worker.organizations
不为空。
我不知道这段关系,你可以尝试这样,让我知道如果它不起作用会发生什么,那么我强烈建议发布关系概念的模型。
问题更新后更新2
首先,您不需要through
关系,因为它使用过Many To Many
关系。您的关系是One To One
,那么您的模型将如下所示
class StratumWorker < ApplicationRecord
has_one :organization_worker
....
has_one:organization,:through =&gt; :organization_worker 德尔>
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
....
然后动作看起来像这样
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)
我认为现在问题会解决。如果仍然存在错误,请再次阅读One To One
关系&amp;再次清除关系概念。
希望它会有所帮助。
答案 1 :(得分:1)
在ID生成的引擎下调用的方法是to_param
因此,在您的情况下,要获得所需的结果,您应该将其添加到Organization
班级:
class Organization < ApplicationRecord
...
def to_param
name
end
...
end
!!!警告!!! - 由于Rails也使用另一方的参数(例如在show方法Organization.find(params[:id])
中使用URL id),现在它将是{ {1}}因此,相应地更改实例查找 - 在params[:id] == "some_organization_name"
操作中,例如使用show
等等
至于您的路由错误 - 请确保Organization.find_by!(name: params[:id])
不是worker.organization
。
答案 2 :(得分:1)
有一个gem friendly_id可以满足您的要求:https://github.com/norman/friendly_id
你添加,
gem 'friendly_id'
然后bundle install
并运行rails generate friendly_id
和rails db:migrate
到您的Gemfile,
class Organization < ApplicationRecord
extend FriendlyId
friendly_id :name, use: :slugged
end
然后到你的模型,
class OrganizationController < ApplicationController
def show
@user = Organization.friendly.find(params[:id])
end
end
到您的控制器。
这可以防止你在Kkulikovskis中遇到的问题,你必须确保你正确地查找。
答案 3 :(得分:1)
我刚刚写了一篇文章here详细说明了这一点。我的大部分答案都是从那里开始的。相关的Rails文档是here。
快速定义:
organization_name
id
。如果您输入organization_path(@organization)
,它会自动使用网址中的id
属性。要调整为使用organization_name
,您需要进行2次更改:
routes.rb
文件中的路线参数。to_param
方法目前,如果您运行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
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/: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
默认情况下,organization.to_param
将返回组织的id
。这需要被覆盖,通过修改模型来执行此操作:
class Organization < ApplicationRecord
def to_param
organization_name
end
end
您现在可以像往常一样继续使用重定向和表单,但现在使用组织名称而不是使用id
的路由。
另外,祝你的采矿池好运! Lemme知道你正在挖掘哪枚硬币,我可能会加入!
另外,我没有说明这一点,因为它不是原始问题的一部分,但是,您应该确保organization_name
是唯一的!您不仅应该在模式中添加唯一性约束validates :organization_name, uniqueness: true
,还应该在迁移中在数据库级别强制执行它。
当您的路线定义如下:
resources :organizations, :only => [:show] 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_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
像这样更改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
将您的路线改为
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
哪个应该可以完全正常使用重定向。