Redirect users#edit to /settings? - ruby-on-rails

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.

Related

Rails redirection to show when redirected to other action in same class

My Task is to submit a form to place_order action inside Checkout controller.
This is how I wrote form in my view file i.e
<%= form_for (#order), url: {action: "place_order"} do |f| %>
It does reach inside this method and as I save object i want to redirect to some other method in the same class. This method name is thank_you. My code looks like this inside place_order method
if #order.save
redirect_to :action => 'thank_you'
else
...
end
But it redirects to show method of this class. If I change redirect to other class, it redirects fine but on other action of same controller, it always redirects to show.
Here is how I defined my routes
resources :checkout
resources :photos
devise_for :users
resources :carts
post 'checkout/place_order'
match 'checkout/thank_you', to: 'checkout#thank_you', via: [:get]
I need some expert opinion on this. Please help.
Move your thank_you route above resources :checkout.
From Rails guides:
Rails routes are matched in the order they are specified, so if you
have a resources :photos above a get 'photos/poll' the show action's
route for the resources line will be matched before the get line. To
fix this, move the get line above the resources line so that it is
matched first.

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!

newbie: how to get dynamic links for current_user?

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.

custom action in rails 3

I'm trying to make a simple link that will toggle my "status" attribute in my model from "pending" to "active". For example, when I first create a user, I set the status to "pending". Then when I show the list of users, I add a button that should change that user's status to "active". I tried this via a custom action (is this a good approach?) but I'm having trouble with the auto-generated named route.
in my user index.html.haml:
button_to "Manually Activate", activate_user_path
in routes.rb:
resources :users do
get :activate, :on => :member
in users_controller.rb:
def activate
#user = User.find(params[:id])
#user.update_attribute(:status, 'Active')
redirect_to #user
end
this seems to work when I go to say, /users/1/activate, as the status will update. However, the /users page doesn't show and gives me error:
ActionController::RoutingError in Users#index
No route matches {:action=>"activate", :controller=>"users"}
ie, it is having a problem with the activate_user_path I specified in my view. (However if I use another named-routes-style path that I haven't specified in my routes.rb to test it out, I get
NameError in Users#index
undefined local variable or method `blahblah_user_url' for #<#<Class:0x00000102bd5d50>:0x00000102bb9588>
so it seems that it knows it's in the routes.rb but something else is wrong? I'm really new to rails and would appreciate the help!
thanks!
Your link should look like this:
button_to "Manually Activate", activate_user_path(#user)
You need to add what user you want to activate.
A number of problems, I can see.
Firstly you should NOT update the database using a GET request.
Secondly button_to will provide you with an inplace form which when clicked will POST to your app.
Thirdly, the way you have your routes setup, you need to provide the user in the path (you've tested it by forming the url in the browser already).
run
rake routes
on the command prompt to see how your routes look and the name you can use to generate those routes.
I suspect you need to use
button_to "Manually Activate", activate_user_path(user)
(user or #user or whatever is the user object). In your button_to call and change the "get" to "post" in the routes file.
resources :users do
member do
post :activate
end
end

Changing the id parameter in Rails routing

Using Ruby on Rails 3's new routing system, is it possible to change the default :id parameter
resources :users, :key => :username
come out with the following routes
/users/new
/users/:username
/users/:username/edit
...etc
I'm asking because although the above example is simple, it would be really helpful to do in a current project I'm working on.
Is it possible to change this parameter, and if not, is there a particular reason as to why not?
In your route you can use
resources :user, param: :username
If I understand you correctly, what you want is to have the username instead of id in your url, right?
You can do that by overriding the to_param method in your model. You can get more information here.
For Ruby on Rails 4.1.4 (and possibly earlier versions) you need to do what both j.. and Ujjwal suggested:
1) In config/routes.rb, add:
resources :user, param: :username
2) In app/models/user.rb, add:
def to_param
username
end
In you only do #1 then all your routes will be correct, as can be seen from rake routes:
$ rake routes
Prefix Verb URI Pattern Controller#Action
user_index GET /user(.:format) user#index
POST /user(.:format) user#create
new_user GET /user/new(.:format) user#new
edit_user GET /user/:username/edit(.:format) user#edit
user GET /user/:username(.:format) user#show
PATCH /user/:username(.:format) user#update
PUT /user/:username(.:format) user#update
DELETE /user/:username(.:format) user#destroy
However the helper methods that construct a url based on a User instance will still include the id in the url, e.g. /user/1. To get the username in the constructed urls, you need to override to_param as in #2.
Although the answer has been accepted by the asker, but there is a simple approach to do this. Write this code in your controller.
authorize_resource :find_by => :username
and in your view, where you want to show the link, write this code.
<%= link_to "Username", user_path(u.username) %>
You don't need any other changes in your routes or controller.
UPDATE: This will only work if you are using CanCan gem.
Pass the user name as the input to the path helpers.
In your view code:
user_path(u.username) #/users/john
In your controller treat the id received as username:
def show
user = User.find_by_username!(params[:id])
...
end

Resources