Rails路由:name而不是:id url参数
我有一个名为’公司’的控制器,而不是每个公司的url用以下表示:id我想让url使用他们的:名称如: url/company/microsoft
而不是url/company/3
。
在我的控制器中我假设我会
def show @company = Company.find(params[:name]) end
由于url中没有任何其他参数,我希望rails能理解:name引用了我公司模型中的:name列。 我认为这里的魔法会在路线上,但我在这一点上陷入困境。
params
最重要的是你正在寻找错误的解决方案 – params
散列键是无关紧要的,你需要能够更有效地使用其中包含的数据。
您的路线将构建为:
#config/routes.rb resources :controller #-> domain.com/controller/:id
这意味着如果您请求此路由: domain.com/controller/your_resource
params[:id]
哈希值将是your_resource
(如果它被称为params[:name]
或params[:id]
则无关紧要)
–
friendly_id
你有几个答案推荐friendly_id
的原因是因为这会覆盖ActiveRecord
的find
方法,允许你在查询中使用slug
:
#app/models/model.rb Class Model < ActiveRecord::Base extend FriendlyId friendly_id :name, use: [:slugged, :finders] end
这允许您这样做:
#app/controllers/your_controller.rb def show @model = Model.find params[:id] #-> this can be the "name" of your record, or "id" end
Rails 4.0+的答案很好:
resources :companies, param: :name
您可以选择only:
使用only:
或except:
list来指定路由
如果要构造URL,可以覆盖相关模型的ActiveRecord :: Base#to_param:
class Video < ApplicationRecord def to_param identifier end # or alias_method :to_param, :identifier end video = Video.find_by(identifier: "Roman-Holiday") edit_videos_path(video) # => "/videos/Roman-Holiday"
老实说,我只会覆盖模型中的to_param
。 这将允许company_path
帮助程序正常工作。
注意:我会为复杂的名称创建一个单独的slug列,但这只是我。 这是一个简单的案例。
class Company < ActiveRecord::Base def to_param name end end
然后更改我的路线param
以便于阅读。
# The param option may only be in Rails 4+, # if so just use params[:id] in the controller resources :companies, param: :name
最后在我的控制器中,我需要以正确的方式查找它。
class CompaniesController < ApplicationController def show # Rails 4.0+ @company = Company.find_by(name: params[:name]) # Rails < 4.0 @company = Company.find_by_name(params[:name]) end end
我建议为此目的使用friendly_id。 请注意,friendly_id 4和5之间存在差异。在friendly_id 4中,您可以像这样使用
@company = Company.find(params[:id])
但是,您将无法在friendly_id 5中执行此操作,您必须使用:
@company = Company.friendly.find(params[:id])
如果您不想使用params [:id]但是params [:name],则必须覆盖routes.rb中的路由。 例如
get '/companies/:name', to: "companies#show"
希望这些信息对您有所帮助
实现这一点实际上没有任何魔力,您必须通过在您的模型上正确实现to_param
(不推荐)或使用其中一个可用的gem来自己构建它 :
- friendly_id
- has_permalink
我使用friendly_id
,它很好地完成了工作。
Model.find(primary_key)
这里的默认参数是primary_key id。 如果你想使用其他列,你应该使用Model.find_by_xxx,所以它可以
def show @company = Company.find_by_name(params[:name]) end