newbie: how to get dynamic links for current_user? - ruby-on-rails

Im trying to figure out how to get a dynamic link for example
/users/user1/show
/users/user1/edit
or
/profiles/1/
How would I create a route that I could insert in my views like a view_profile_path and that would include the id or username of a user?

in config/routes.rb you need to add 1 simple line:
resources :users
and get all this stuff
HTTP Verb Path action named helper
GET /users index users_path
GET /users/new new new_user_path
POST /users create users_path
GET /users/:id show user_path(:id)
GET /users/:id/edit edit edit_user_path(:id)
PUT /users/:id update user_path(:id)
DELETE /users/:id destroy user_path(:id)
You can read about rails routes in the guides

Actually, I think you need something like this in config/routes.rb
resources :users do
resources :profiles
end
You can later check your REST-ful resource routes by issuing the command:
rake routes
This way you have a more natural approach to your routes in which your users will be bound to one or more profiles, therefore you may use something like:
user_profile_path(#user)
to create an appropriate link to a user's profile.

Related

Redirect users#edit to /settings?

I want the users#edit action to always be displayed as /settings.
In my routes I have
get "settings" => "users#edit", as: :settings
Any link to settings is like this
<%= link_to "Settings", settings_path %>
But when I visit example.com/username/edit, it doesn't redirect.
How can I redirect this to settings? And is this a bad practice?
I think you meant to do this instead
get '/username/edit', to: redirect('/settings')
the one you did above is trying to have that url use a method called
edit in users_controller with alias of settings to be used as settings_path in your link somewhere
It is always helpful to look at Rails API for these kinds of questions
Ref: http://guides.rubyonrails.org/routing.html#redirection
By defining a new route settings you are telling Rails to route all GET requests that come to /settings to the users_controller's edit method. This does not mean that all requests that use that controller should redirect to another route - here you have just defined two separate routes that use the same controller method.
If you don't want to use user/edit ever, then I suggest you remove the route. If you currently have something like
# config/routes.rb
resources :users
Simply change it to
# config/routes.rb
resources :users, except: [:edit]
And keep using your settings_path helper.

Modify routes in rails

I'm a new user of rails so it's complicated to understand how the routes.rb works! So I try to modify a route, I got a path that look like this:
user/:id/edit but i want that the id not appear in the path.
I try to use this method :
get '/users/:id/edit', to: 'users#edit', as: 'users/edit'
but it changes nothing. In my routes.rb i got :
resources :users, only: [:create, :new, :show, :edit]
Someone know how to do this? I already take a look at this guide
If you already take a look at guides, do you read about singular resources?
Sometimes, you have a resource that clients always look up without
referencing an ID. For example, you would like /profile to always show
the profile of the currently logged in user. In this case, you can use
a singular resource to map /profile (rather than /profile/:id) to the
show action:
resource :geocoder
creates six different routes in your application, all mapping to the Geocoders controller:
GET /geocoder/new geocoders#new return an HTML form for creating the geocoder
POST /geocoder geocoders#create create the new geocoder
GET /geocoder geocoders#show display the one and only geocoder resource
GET /geocoder/edit geocoders#edit return an HTML form for editing the geocoder
PATCH/PUT /geocoder geocoders#update update the one and only geocoder resource
DELETE /geocoder geocoders#destroy delete the geocoder resource
If you have taken,
resources :users
Now change this route as follows,
get '/users/edit', to: 'users#edit', as: 'users_edit'
Now in your view file where you have edit link, change the link to,
<%= link_to 'Edit', users_edit_path(:id => user.id) %>
Now this links to the edit action of users controller with an id parameter.
Now, in the users controller file,
class UsersController < ApplicationController
def edit
// params[:id] will be the ID that you sent through the view file.
#user = User.find(params[:id])
end
end
Thats it, you are done with your custom route, now the route will be users/edit instead of users/:id/edit

Allowing user to edit account without the :id param in the url

Hi I'd like to accomplish having a URL that's
users/edit
instead of the current
users/7/edit
I have my own auth system built upon omniauth. Thus I store their user_id in a session. How would I go about accomplishing this task?
Assuming that you use current_user, even if you are using something else just replace current_user with your method, I am using current_user here, follow these steps,
Create an action, I would name it edit_user in your users controller
def edit_user
#user = current_user # or User.find(session[:user_id])
end
Add routes to routes.rb
get "/users/edit" => "users#edit_user"
You are done, you can use the above route anywhere in the application, you can also name the route if needed.
OR, if you don't want to define a new action and want to use the existing edit action, do this
Remove routes for edit from the default resources routes and then manually define it. In this way, you can use the existing edit action
resources :users, except: [:edit]
get "/users/edit" => "users#edit"
Hope this helped!

route works one place, not others

This is kind of difficult to communicate but I'll try without pasting all my code. I have Members who have one Mailbox which has many Receipts. In the header layout I have a nav that calls
<%= link_to "Message Center", member_mailbox_path(current_user.member_id) %>
It works on most pages like trails/# , the resource pages for various models
But on other pages, seems like custom route pages, I get this error
No route matches {:action=>"show", :controller=>"mailbox", :member_id=>16}
Running rake routes shows this:
member_mailbox GET /members/:member_id/mailbox/:id(.:format) mailbox#show
Routes are confusing to me, here are my routes for this problem (show message isn't tested yet) ...
resources :members do
resources :mailbox do
resources :receipts do
member do
get :show_message
end
end
end
end
The routes for the pages that are showing the error are similar to this one
match '/my_plays', :to => "trails#my_plays"
match '/my_creations', :to => "trails#my_creations"
So not sure if my routes are right. I wonder if resources :mailbox is correct since I don't have a bunch of resources for that, it's a has_one .... THX
----EDIT--- after changing route per advice:
member_mailbox POST /members/:member_id/mailbox(.:format) mailboxes#create
new_member_mailbox GET /members/:member_id/mailbox/new(.:format) mailboxes#new
edit_member_mailbox GET /members/:member_id/mailbox/edit(.:format) mailboxes#edit
GET /members/:member_id/mailbox(.:format) mailboxes#show
PUT /members/:member_id/mailbox(.:format) mailboxes#update
DELETE /members/:member_id/mailbox(.:format) mailboxes#destroy
You may want to define a mailbox as a singular resource in your routes. Otherwise, Rails will expect you to pass in both the user id and the mailbox id for member_mailbox_path to route to mailbox#show. I believe this is why you're getting a routing error. Since each user has one mailbox, there's no need to make this extra lookup part of the route. So instead of resources :mailbox, you can do resource :mailbox:
resources :members do
resource :mailbox do
resources :receipts do
member do
get :show_message
end
end
end
end
I believe this would generate the following routes:
member_mailbox POST /members/:member_id/mailbox(.:format) mailboxes#create
new_member_mailbox GET /members/:member_id/mailbox/new(.:format) mailboxes#new
edit_member_mailbox GET /members/:member_id/mailbox/edit(.:format) mailboxes#edit
GET /members/:member_id/mailbox(.:format) mailboxes#show
PUT /members/:member_id/mailbox(.:format) mailboxes#update
DELETE /members/:member_id/mailbox(.:format) mailboxes#destroy
Notice that the lack of path names next to GET, PUT, and DELETE doesn't mean they don't exist; they're just repeats of the POST path, but each responds to different HTTP methods.
To render mailboxes#show, you'll need to add a MailboxesController with a show route, which might do a look up for the member:
class MailboxesController < ApplicationController
def show
#member = Member.find(params[:member_id])
# other mailbox code...
end
end
And you'll also create a template at app/views/mailboxes/show.html.erb to render the mailbox show page.
Also, I would recommend against deeply nesting your routes, as in third level :receipts.

rails nested resources handle edit path as id

I have the following routes
resources :users, path: '/' do
resources :posts, path: '/'
end
the problem is that the inner route override the outer route for user's edit path.
http://localhost/user/edit refer to posts#show instead users#edit
EDIT
Singular resource is not the solution, I want to access the user via his ID.
lets say I have user with id "Jo" and post with id "My-First-Post", then the corresponding route should be http://localhost/Jo/My-First-Post. that's work just fine with my current solution.
the problem is that when I access /Jo/edit I get exception that there is no post with id "edit" while I want this route to refer to Jo's edit page (users#edit)
What are you trying to achieve? It sort of looks like you want a singular resource. If that's the case, you can just do:
routes.rb
resource :user
So just make the word resource and user singular. Then you'll get singular routes, like user/edit.
See the Rails guide for more information: http://guides.rubyonrails.org/routing.html#singular-resources

Resources