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"
to_param
method, read more aboutto_param
method here – rails_id