Timmy Von Heiss
Timmy Von Heiss

Reputation: 2218

What is the path for this route?

get 'users/:id/edit/settings' => 'users#account'

What is the dry way to reference this path in link_to?

As a side note, I use 'users/:id/edit' to edit name/location/age etc and I am using the route above to edit password and email, because I wish to force the user to authenticate their :current_password before editing these more sensitive attributes. I mention this just to make sure my routing logic is correct.

Upvotes: 1

Views: 60

Answers (4)

max
max

Reputation: 102194

You can use the as: option to setup a named route.

However I would set it up with conventional rails routes:

Rails.application.routes.draw do
  resources :users do
    resource :settings, only: [:edit, :update], module: :users
  end
end

This would create an idiomatically correct RESTful route.

Using the singular resource creates routes without an id parameter. Also you should only use the name :id for the rightmost dynamic segment in a route to avoid violating the principle of least surprise.

rake routes will show you the following routes:

            Prefix Verb   URI Pattern                             Controller#Action
edit_user_settings GET    /users/:user_id/settings/edit(.:format) users/settings#edit
     user_settings PATCH  /users/:user_id/settings(.:format)      users/settings#update
                   PUT    /users/:user_id/settings(.:format)      users/settings#update
...

As a side note, I use 'users/:id/edit' to edit name/location/age etc and I am using the route above to edit password and email, because I wish to force the user to authenticate their :current_password before editing these more sensitive attributes. I mention this just to make sure my routing logic is correct.

Your route will in no way enforce this authorization concern.

Instead you should do a check in your controller:

# app/models/users/settings_controller.rb
class Users::SettingsController
  before_action :set_user
  before_action :check_password, except: [:edit]

  def edit
    # ...
  end

  def update
    # ...
  end

  private 

  def set_user
    @user = User.find(params[:user_id])
  end

  def check_password
    # this is an example using ActiveModel::SecurePassword
    unless @user.authorize(params[:current_password])
      @user.errors.add(:current_password, 'must be correct.')
    end
  end
end

Upvotes: 1

Pragun
Pragun

Reputation: 1241

rake routes will probably give you a path something like users_path which you can link to using something like <%= link_to 'Users', users_path(@id) %>

Upvotes: 0

David
David

Reputation: 3610

change it to:

get 'users/:id/edit/settings' => 'users#account', as: :edit_user_settings

and then you can just reference it as:

link_to edit_user_settings_path(@user)

Upvotes: 0

C dot StrifeVII
C dot StrifeVII

Reputation: 1885

Just run rake routes and you will see all the routes that you have in you app. It should be to the far right

Upvotes: 1

Related Questions