Rails routes with :name instead of :id url parameters

前端 未结 7 2025
渐次进展
渐次进展 2020-12-05 13:05

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/comp

7条回答
  •  北荒
    北荒 (楼主)
    2020-12-05 13:40

    The :id parameter is whatever comes after the slash when the URL is requested, so a name attribute needs to be extracted from this by checking the :id parameter for non-numerical values with regular expressions and the match? method in the controller. If a non-numerical value is present, the instance can be assigned by the name attribute using the find_by_name() method that rails generated for the model (assuming that the model has an attribute called name)

    That's how I figured out how to do it in my app with my Users resource. My users have a username attribute, and all I had to do was modify the UsersController to define my @user variable differently depending on the :id parameter:

    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
    

    This gives me the option to use either id or username when I create a link to a particular user, or type it into the browser's address bar.

    Then the only other (optional) thing to do is to change all the links in the views so that they point to the URL with the name instead of the URL with the id.

    For example, within the link_to() method call in my navigation bar I changed

    ... user_path(current_user) ...
    

    to

    ... user_path(current_user.username) ...
    

    In your example, you might have a company view with the following link:

    <%= link_to @company.name, company_path(@company.name) %>
    

    Which, if the current company is Microsoft, would display "Microsoft" and link to "companies/Microsoft", even though the URL "companies/1" would still be valid and display the same thing as "companies/Microsoft"

提交回复
热议问题