Change the name of the :id parameter in Routing resources for Rails

前端 未结 5 1429
难免孤独
难免孤独 2020-12-04 10:11

I looked around on how to change the dynamic params slot and found this post that does the exact thing. The post is https://thoughtbot.com/blog/rails-patch-change-the-name-o

相关标签:
5条回答
  • 2020-12-04 10:23

    in Rails 4, pass param option to change the :id params. For example resources :photos, param: :photo_name will generate /photos/:photo_name

    0 讨论(0)
  • 2020-12-04 10:27

    There's a gem for that, just like there's a gem for everything ;)

    I've been using FriendlyId for this kind of behaviour in rails 3.

    It will require you to add some code to your model though, like this:

    class Client < ActiveRecord::Base
      has_friendly_id :name
    end
    

    ...and if your clients don't have URI compatible names, you might want to use a slug for that, which you can do with has_friendly_id :name, :use_slug => true. When using slugs you'll obviously need to persist them to the database as well though.

    And as already mentioned, you can still use the to_param trick with rails 3, as documented here. I find FriendlyId a bit more versatile though.

    0 讨论(0)
  • 2020-12-04 10:36

    In Rails 3 you can rename the id keys by using a combination of namespaces and scopes like this (not very nice though):

    namespace :clients do
      scope "/:client_name" do
        namespace :sites do
          scope "/:name" do
             post "/:title" => "articles#create"
             ...
          end
        end
      end
    end
    
    0 讨论(0)
  • 2020-12-04 10:41

    Rails 4 & 5

    In Rails 4, the :param option was added, which seems to do exactly what you're looking for. You can take a look at the Rails 3 code compared to the Rails 4 code.

    Details

    You can easily implement this in your routes.rb file:

    # config/routes.rb
    
    resources :posts, param: :slug
    
    # app/controllers/posts_controller.rb
    
    # ...
    @post = Post.find_by(slug: params[:slug])
    # ...
    

    As of the release of Rails 4, this functionality is documented in the Rails Guides.

    Rails 3

    Unfortunately, in Rails 3, the :key option for resources was removed, so you can no longer easily change the name for routes created in this way by just passing in an extra option.

    Details

    I assume you've already somehow gotten the application working the way you want in the past year, but I will go into a way to get the effect you describe in Rails 3 in routes.rb. It will just involve a bit more work than the to_param method. You can still define custom parameters in routes defined using scope and match (or it's cousins get, put, post, and delete). You simply write in the parameter name you want in the matcher:

    get 'clients/:client_name', :to => 'clients#show', :as => client
    
    scope 'clients/:client_name' do
      get 'sites/:name', :to => 'sites#show', :as => site
    end
    

    You would have to manually add all the routes that resources automatically creates for you, but it would achieve what you're looking for. You could also effectively use the :controller option with scope and additional scope blocks to take out some of the repetition.


    EDIT (May 8, 2014): Make it more obvious the answer contains information for both Rails 3 & 4. Update the links to the code to go to exact line numbers and commits so that they should work for a longer period of time.

    EDIT (Nov 16, 2014): Rails 4 should be at the top now and include relevant information as it's been the current version of Rails for quite some time now.

    EDIT (Aug 9, 2016): Reflect that the solution still works in Rails 5, and update outdated links.

    0 讨论(0)
  • 2020-12-04 10:45

    If I understand you correctly, what you want is to have the client_name instead of id in your url, right?

    You can do that by overriding the to_param method in your model. You can get more information here.

    0 讨论(0)
提交回复
热议问题