Rails routes with :name instead of :id url parameters

匿名 (未验证) 提交于 2019-12-03 01:56:01

问题:

I have a controller named 'companies' and rather than the urls for each company being denoted with an :id I'd like to have the url use their :name such as: url/company/microsoft instead of url/company/3.

In my controller I assumed I would have

 def show    @company = Company.find(params[:name])  end 

Since there won't be any other parameter in the url I was hoping rails would understand that :name referenced the :name column in my Company model. I assume the magic here would be in the route but am stuck at this point.

回答1:

params

The bottom line is you're looking at the wrong solution - the params hash keys are rather irrelevant, you need to be able to use the data contained inside them more effectively.

Your routes will be constructed as:

#config/routes.rb resources :controller #-> domain.com/controller/:id 

This means if you request this route: domain.com/controller/your_resource, the params[:id] hash value will be your_resource (doesn't matter if it's called params[:name] or params[:id])

--

friendly_id

The reason you have several answers recommending friendly_id is because this overrides the find method of ActiveRecord, allowing you to use a slug in your query:

#app/models/model.rb Class Model 

This allows you to do this:

#app/controllers/your_controller.rb def show     @model = Model.find params[:id] #-> this can be the "name" of your record, or "id" end 


回答2:

Good answer with Rails 4.0+ :

resources :companies, param: :name 

optionally you can use only: or except: list to specify routes

and if you want to construct a URL, you can override ActiveRecord::Base#to_param of a related model:

class Video  "/videos/Roman-Holiday" 


回答3:

Honestly, I would just overwrite the to_param in the Model. This will allow company_path helpers to work correctly.

Note: I would create a separate slug column for complex name, but that's just me. This is the simple case.

class Company 

Then change my routes param for readability.

# The param option may only be in Rails 4+, # if so just use params[:id] in the controller resources :companies, param: :name 

Finally in my Controller I need to look it up the right way.

class CompaniesController 


回答4:

I recommend using the friendly_id for this purpose. Please be noted that there are differences between friendly_id 4 and 5. In friendly_id 4, you can use like this

 @company = Company.find(params[:id]) 

However, you won't be able to do that in friendly_id 5, you have to use:

 @company = Company.friendly.find(params[:id]) 

In case that you don't want to use the params[:id] but params[:name], you have to override the route in routes.rb. For example

 get '/companies/:name', to: "companies#show" 

Hope these info would be helpful to you



回答5:

There's actually no magic to implement this, you have to either build it yourself by correctly implementing to_param at your model (not recommended) or using one of the gems available for this like:

I use friendly_id and it does the job nicely.



回答6:

Model.find(primary_key)
The default parameter here is primary_key id. If you want to use other columns, you should use Model.find_by_xxx so here it could be

def show   @company = Company.find_by_name(params[:name]) end 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!