我有一个名为'公司'而不是每个公司的网址都用以下内容表示:id我想让网址使用他们的名称:url/company/microsoft
代替url/company/3
。
在我的控制器中,我以为我会有
def show
@company = Company.find(params[:name])
end
由于url中没有任何其他参数,我希望rails能理解:name引用了我公司模型中的:name列。我认为这里的魔法会在路线上,但我现在陷入困境。
答案 0 :(得分:65)
Rails 4.0+的答案很好:
resources :companies, param: :name
您可以选择使用only:
或except:
列表来指定路线
如果你想构建一个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"
答案 1 :(得分:11)
<强> params
强>
最重要的是你正在寻找错误的解决方案 - params
哈希键是无关紧要的,你需要能够更有效地使用其中包含的数据。
您的路线将构建为:
#config/routes.rb
resources :controller #-> domain.com/controller/:id
这意味着如果您请求此路线:domain.com/controller/your_resource
,则params[:id]
哈希值将为your_resource
(如果它被称为{{1}则无关紧要}或params[:name]
)
-
<强> friendly_id
强>
您有多个答案推荐params[:id]
的原因是因为这会覆盖friendly_id
的{{1}}方法,允许您在查询中使用slug
:
find
这允许您这样做:
ActiveRecord
答案 2 :(得分:11)
老实说,我只会覆盖模型中的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
最后在我的 Controller 中,我需要以正确的方式查找。
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
答案 3 :(得分:6)
我建议将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"
希望这些信息对您有所帮助
答案 4 :(得分:5)
实现这一点实际上没有什么神奇之处,您必须build it yourself通过在您的模型上正确实施to_param
(不推荐)或使用其中一个可用的宝石,如:
我使用friendly_id
,它可以很好地完成工作。
答案 5 :(得分:2)
Model.find(primary_key)
这里的默认参数是primary_key id。
如果要使用其他列,则应使用Model.find_by_xxx
所以这里可能是
def show
@company = Company.find_by_name(params[:name])
end
答案 6 :(得分:0)
:id参数是在请求URL时出现在斜杠之后的内容,因此需要通过检查:id参数是否包含正则表达式和匹配项的非数字值来从中提取名称属性?控制器中的方法。如果存在非数字值,则可以使用为模型生成的rails的find_by_name()方法由name属性分配实例(假设模型具有名为name的属性)
这就是我想出如何使用我的用户资源在应用程序中进行操作的方式。我的用户有一个username属性,我要做的就是修改UsersController,以根据:id参数以不同的方式定义我的@user变量:
private
# allow routing by name in addition to id
def get_user
if params[:id].match?(/\A\d+\Z/)
# if passed a number, use :id
@user = User.find(params[:id])
else
# if passed a name, use :username
@user = User.find_by_username(params[:id])
end
end
当我创建指向特定用户的链接或在浏览器的地址栏中键入链接时,这使我可以选择使用id或用户名。
然后唯一要做的另一件事是更改视图中的所有链接,以使它们指向具有名称的URL而不是具有ID的URL。
例如,在我更改的导航栏中的link_to()方法调用中
... user_path(current_user) ...
到
... user_path(current_user.username) ...
在您的示例中,您可能具有以下链接的公司视图:
<%= link_to @company.name, company_path(@company.name) %>
即使当前的公司是Microsoft,即使URL“ companies / 1”仍然有效并且显示的内容与“ companies / Microsoft”相同,也会显示“ Microsoft”并链接到“ companies / Microsoft”。