nicholas79171
nicholas79171

Reputation: 1273

Missing params when updating only single attribute in Rails

I would like the site's admin to be able to update permissions for users. My user model has an attribute permissions_id which is simply an integer that doesn't even relate to another table, just a number I'll reference later.

The error I'm getting is param is missing or the value is empty: user when going to the users/:id/choose_permissions URL. I figured that the rest of the user's information will be passed to the controller when it tries to update the user, but it doesn't see the user I'm passing it.

I've tried switching the params to params.fetch(:user, {}).permit(...) as suggested here but it just skips over the form whenever I go to users/:id/choose_permissions.

app/controllers/users_controller.rb

def choose_permissions
  @user = User.find(params[:id])
  if @user.update_attributes(user_params)
    flash[:success] = "User updated"
    redirect_to @user 
  else
    render 'update_permissions'
  end
end

private

  def user_params
    params.require(:user).permit(:name, :email, :password, 
                                 :password_confirmation, :permissions_id)
  end

app/views/users/choose_permissions.html.erb

<%= form_for(@user) do |f| %>

  <%= f.label "Choose permissions" %>
  <%= f.password_field :permissions_id, class: 'form-control' %>

  <%= f.submit "Save changes", class: "btn btn-primary" %>
<% end %> 

config/routes.rb

resources :users do
  member do
    get :choose_permissions
  end
end

Is it because this page is a GET request instead of a PATCH? Or is it possibly because an admin is trying to update another user?

Upvotes: 2

Views: 408

Answers (1)

CV-Gate
CV-Gate

Reputation: 1170

Problem is in your controller, you should split the edit and update actions this way:

def edit_choose_permissions
  @user = User.find(params[:id])
end

def update_choose_permissions
  @user = User.find(params[:id])
  if @user.update_attributes(user_params)
    flash[:success] = "User updated"
    redirect_to @user 
  else
    render 'edit_update_permissions'
  end
end

As you are not following REST, you should specify the url in your form:

<%= form_for(@user, url: update_choose_permissions_path(@user)) do |f| %>

Also for your routes, you'll have to rewrite them this way:

get 'users/:id/choose_permissions, to: 'users#edit_choose_permissions', as: 'edit_choose_permissions'
patch 'users/:id/choose_permissions, to: 'users#update_choose_permissions', as: 'update_choose_permissions'

Disclaimer: not tested.

Upvotes: 1

Related Questions