hrsetyono
hrsetyono

Reputation: 4464

Rails 4 - No route matches PATCH on custom route

I need a page for changing Profile of current user, it's weird if the url is /user/:id, so I map it to /settings

get "/settings", to: "users#edit", as: "settings_user"

But when I submit the form I got this error:

Routing Error

No route matches [PATCH] "/settings"

The weird part is if I press back and re-submit the form, it will submit just fine.

If I go to another page then back to the form, it will get error on first try but works fine on second try onward.

My controller:

class UsersController < ApplicationController
  ...
  def edit
    @user = current_user #this is the cache of currently logged in user
  end

  def update
    @user = User.find(params[:id])
    if @user.update(user_params)
     redirect_to settings_user_path, notice: "Profile has been saved"
    end
  end

  private
    def user_params
      params.require(:user).permit(:id, :name, :email, :bio)
    end
end

My view:

<%= form_for @user do |f| %>
  ...
<% end %>

Note:

Other page that are using the default route like my Product page works fine, so it's not the Rails config problem.

Upvotes: 2

Views: 1834

Answers (2)

hrsetyono
hrsetyono

Reputation: 4464

This issue only occur on Chrome 37 Beta. I reverted back to Chrome 36 Release and everything works fine.

I guess I won't use the beta version for daily use ever again.

Upvotes: 0

Richard Peck
Richard Peck

Reputation: 76774

Devise

I guess you're using devise (by how you're using current_user) - so you may wish to look at Devise' custom routing paths. Although this won't provide a routing structure for your user object, it may come in handy some time:

#config/routes.rb
devise_for :users, path: "auth", path_names: { sign_in: 'login', sign_out: 'logout', password: 'secret', confirmation: 'verification', unlock: 'unblock', registration: 'register', sign_up: 'cmon_let_me_in' }

--

Routes

If you want to manage your user object, you'll be best using the resources route definition:

#config/routes.rb
resources :users, only: [], path: "" do
   collection do
       get :settings, action: :edit
       match :settings, action :update, via: [:patch, :put]
   end
end

The problem you have is your form is thinking it should send your update request to /settings too:

No route matches [PATCH] "/settings"

The way around this is to either provide a route for patch (as demonstrated above), OR define the url parameter of the form:

<%= form_for @user, url: your_update_path do |f| %>

--

Hope this helps?

Upvotes: 1

Related Questions