Reputation: 1995
I have a model, Playlist
, which belongs_to
a User
. Instead of the routes for playlists to be
/playlists
/playlists/new
/playlists/:id
/playlists/:id/edit
I would like them to be
/:username/playlists
/:username/playlists/new
/:username/:playlist_slug
/:username/:playlist_slug/edit
But, this has to still work:
playlist_path(@playlist)
# NOT: playlist_path(@playlist.user, @playlist)
Since the user of the path is @playlist.user
. It is not DRY to repeat this parameter every time I need a path. Besides, it is a risk, since it allows for bogus calls. For example playlist_path(@alice, @bob.playlists.first)
.
Upvotes: 1
Views: 107
Reputation: 76774
FriendlyID
is what you want:
#config/routes.rb
resources :users, path: "", only: [] do
resources :playlists #-> url.com/:user_id/playlists
end
#app/models/user.rb
class User < ActiveRecord::Base
has_many :playlists
extend FriendlyID
friendly_id :username, use: [:slugged, :finders]
end
This will automatically populate the paths
and .find
methods with the slug value for your @user
:
#view
<%= link_to @playlist.name, user_playlist_path(@user, @playlist) %>
#app/controllers/playlists_controller.rb
class PlaylistsController < ApplicationController
def show
@user = User.find params[:user_id]
@playlist = @user.playlists.find params[:id]
end
end
--
As per the FriendlyID docs, you'll need to do the following to get it set up:
rails generate friendly_id #-> initializer
rails generate scaffold user name:string slug:string:uniq
rake db:migrate
You'll also want to update your User
model to ensure that each record has a slug
:
$ rails c
$ User.find_each(&:save)
Upvotes: 0
Reputation: 2659
I think you are asking for Friendly id and here is its implementation. Hope this helps
Upvotes: 2