How do I get the format of my URLs to be username/

2019-06-01 02:20发布

问题:

I want it similar to the way Twitter handles the URLs for its tweets.

For instance, right now my URL looks like this: mydomain.com/feedbacks/1/, where feedbacks is the name of the controller.

I want it to look like: mydomain.com/username/feedbacks/1/ which is similar to Twitter's: twitter.com/username/status/:id/.

My routes.rb looks like this:

  resources :users do
      resources :feedbacks
  end

When I have it like this, it gives me the URLs as mydomain.com/users/1/feedbacks, but I want the actual username in the URL.

How do I get that?

Thanks.

Edit 1: If you are adding another answer to this question, please make sure it addresses my comments/questions to the answer already given. Otherwise it will be redundant.

回答1:

scope ":username" do
  resources :feedbacks
end

From the docs:

This will provide you with URLs such as /bob/posts/1 and will allow you to reference the username part of the path as params[:username] in controllers, helpers and views.


UPDATE:

I have tested and confirmed the accuracy of paozac's answer. I'll clarify it a bit.

Suppose you had a @feedback object with an id of 12, and the associated user had a username of foouser. If you wanted to generate a URL to the edit page for that @feedback object, you could do the following:

edit_feedback_url(:username => @feedback.user.username, :id => @feedback)

The output would be "/foouser/feedbacks/12/edit".

# A URL to the show action could be generated like so:
feedback_url(:username => feedback.user.username, :id => feedback)
#=> "/foouser/feedbacks/12"
# New
new_feedback_url(:username => current_user.username)
#=> "/foouser/feedbacks/new"

Additionally, as noted by nathanvda in the comments, you can pass ordered arguments which will be matched with the corresponding dynamic segment. In this case, the username must be passed first, and the feedback id should be passed second, i.e.:

edit_feedback_url(@feedback.user.username, @feedback)

Also, if you need help handling the params from the controller, I suggest creating a new question specific to that.



回答2:

Once you have defined the scope like dwhalen says you can generate the url like this:

feedbacks_url(:username => 'foo')

and get

http://www.example.com/foo/feedbacks

or

edit_feedback_url(:username => 'foo', :id => 1)

and get

http://www.example.com/foo/feedbacks/1/edit