First I am sorry for my English
I am using Friendly_id gem to create Clean URL and it work just fine but instead of having a URL like this http://localhost:3000/profile/jack-sparo I want a URL like this http://localhost:3000/profile/1/jack-sparowhere 1 is the user_id, so how can I do it?
this is my config/routes
get "profiles/show"
get '/profile/:id' => 'profiles#show', :as => :profile
get 'profiles' => 'profiles#index'
and this is my Profile controller
def show
#user= User.find_by_slug(params[:id])
if #user
#posts= Post.all
render action: :show
else
render file: 'public/404', status: 404, formats: [:html]
end
end
If you have an id of the record in URL anyway, you don't need
Friendly_id gem. You need to tune routes.
But maybe you would be happy with something like this instead?
http://localhost:3000/profiles/1-john-smith
If so, you need to override to_param method in User model like
this:
class User < ActiveRecord::Base
def to_param
"#{id}-#{name}".parameterize
end
end
Now the profile_path(profile) helper will generate URL like
http://localhost:3000/profiles/1-john-smith
And, with this request, the User.find(params[:id]) in controller
will find profile with id 1 and cut all other stuff which was in URL.
So
http://localhost:3000/profiles/1-mojombo-smith
will link to the same profile as
http://localhost:3000/profiles/1-john-smith
Related
In my rails blog app, I have posts and pages. I am using friendly_id gem. Is it possible to have clean URLs without the controller for both post and pages at the same time? They should look like that:
example.com/my-post
example.com/my-page
Thank you.
Of course you can, but you will need to be extremly carefully to avoid duplicate slugs between pages and posts.
routes.rb
Rails.application.routes.draw do
get ':id', to: 'pages_posts#show', as: 'page_or_post'
end
pages_posts_controller.rb
class PicturesController < ApplicationController
def show
if #page = Page.friendly.find(params[:id])
render 'pages/show'
elsif #post = Post.friendly.find(params[:id])
render 'posts/show'
else
raise ActiveRecord::RecordNotFound
end
end
end
*.html.erb
link_to 'link', page_or_post_path(id: object.slug)
could one advise me how to get a url like this in rails
http://www.example.com/users/5/ian
i tried the below but unsure:
route file:
devise_for :users
resources :users do
resources :socials
end
get '/users/:id/:firstname', controller: 'users', action: 'show'
users_controller.rb
def show
#user = User.find(params[:id], params[:firstname])
end
If you are trying to achieve 'friendly urls' then I suggest using this:
You don't have to create a special route:
get '/users/:id', controller: 'users', action: 'show'
Instead you have your model overwrite the to_param method:
class User
...
def to_param
"#{id}-#{firstname.try(:parameterize)}"
end
...
end
The url helper calls to_param to build the urls. If you overwrite it this way, you will receive a url like this:
http://localhost:3000/users/1-artloe
The rails find method calls .to_i on the params[:id] which, thankfully, interprets strings as number until it arrives at a character that can't become a number.
Examples:
'123abcde'.to_i # 123
'123-asdf'.to_i # 123
'asdf-123'.to_i # 0
So except for overwriting to_param, you don't have to do anything.
Try replacing this
def show
#user = User.find_by_id_and_firstname(params[:id], params[:firstname])
end
If what you are trying accomplish is "friendly urls" you would do it by:
# GET /users/1
# GET /users/joe
def show
#user = User.find_by!('id = :x OR firstname = :x', x: params[:id])
end
However you must ensure that property you are using in URLs is URL safe and unique. Usually a separate username or slug field is used.
Nothing special is needed in terms of routes.
These gems provide "friendly urls":
stringex
friendly_id
I want to create a profile page for users that signing up
so let's say a user already registered, his profile link should be
website.com/profile/username
and on the
views/profile/index.html.erb
each user should see his own profile and edit it with the form_for I guess
so far I have profiles_controller.rb, profile.rb model and resources :profilesfor my routes.rb
What is the best way to do that?
If you wanna get by username then you need to use slug. The example below is for id version.
Profile controller
def show
#profile = Profile.find(params[:id])
end
routes:
get 'profile/:id' => 'profile#show'
for :slug version, url will be like this: http://localhost:3000/profiles/**username**
routes:
resources :profiles, param: :slug
profiles_controller
def show
end
private
def set_profile
#profile = Profile.find_by_username(params[:slug])
end
Or you can use gem for this https://github.com/norman/friendly_id
Post model change to URL parameters to title
class Post < ActiveRecord::Base
def to_param
"#{id}-#{title}"
end
end
When any one type http://0.0.0.0:3000/posts/4 it redirect to belong particular post
When any one type post id, How redirect to 404 page?
I think you could just check if id is number or no. And do somehing like that:
render file: "#{Rails.root}/public/404.html", layout: false, status: 404
like:
in application.rb:
def check_id(arg)
if params[arg] && params[arg].match(/\A[0-9]+\z/)
render_404
false
end
end
def render_404
render file: "#{Rails.root}/public/404.html", layout: false, status: 404
end
in controller.rb:
before_filter -> { check_id(:id) }
In case you don't want to display a 404 error page from your controller, you can just redirect to your root path like this:
rescue ActiveRecord::RecordNotFound
redirect_to root_path
Method to_param needs to build path to resource: apidock.com/rails/ActiveRecord/Base/to_param
class User < ActiveRecord::Base
def to_param # overridden
name
end
end
user = User.find_by_name('Phusion')
user_path(user) # => "/users/Phusion"
How to make friendly URLs you can find out there
If you want to have user-friendly links, simple way is gem friendly-id
I'd like to create a rails route for editing a user's profile.
Instead of having to use /users/:id/edit, I'd like to have a url like /edit_profile
Is it possible to create a dynamic route that turns /edit_profile into /users/{user's id}/edit, or should I do thing in a controller or?
You might want to create a separate controller for this task but you could also continue using users_controller and just check whether there is a params[:id] set:
def edit
if params[:id]
#user = User.find(params[:id])
else
#user = current_user
end
end
But you should note that /users normally routes to the index action and not show if you still have the map.resources :users route. But you could set up a differently called singular route for that:
map.resources :users
map.resource :profile, :controller => "users"
This way /users would list all the users, /users/:id would show any user and /profile would show the show the currently logged in users page. To edit you own profile you would call '/profile/edit'.
Since a route and controller serve two different purposes, you will need both.
For the controller, assuming you're storing the user id in a session, you could just have your edit method do something like:
def edit
#user = User.find(session[:user_id])
end
Then have a route that looks something like:
map.edit_profile "edit_profile", :controller => "users", :action => "edit"
This route would give you a named route called edit_profile_path
Tomas Markauskas's answer could work, but here's the answer to your question from the Rails Guide:
get 'edit_profile', to: 'users#edit'
So, when someone goes to www.yoursite.com/edit_profile, it will route to www.yoursite.com/users/edit.
Then, in your controller you can access the user with
#user = User.find(session[:current_user_id])
Assuming you set that session variable when someone logs in. Also, don't forget to check if they're logged in. This will work if your using Resourceful Routing (the Rails default) or not.
Source: http://guides.rubyonrails.org/routing.html
make the route as
get '/users/:id/edit', to: 'users#edit', as: 'edit_profile'
As explained in this link section 'The hard way' :
http://augustl.com/blog/2009/styling_rails_urls/
The url will be
/users/edit_profile
Because the ID is no longer in the URL, we have to change the code a bit.
class User < ActiveRecord::Base
before_create :create_slug
def to_param
slug
end
def create_slug
self.slug = self.title.parameterize
end
end
When a user is created, the URL friendly version of the title is stored in the database, in the slug column.
For better understanding read the link below
http://blog.teamtreehouse.com/creating-vanity-urls-in-rails
write it in any home controler.
def set_roots
if current_user
redirect_to dashboard_home_index_path
else
redirect_to home_index_path
end
end
in routes.rb file
root :to => 'home#set_roots'
match "/find_roots" => "home#set_roots"