新手问题 修改用户信息提示错误:param is missing or the value is empty: user

dorbod · 2016年01月07日 · 最后由 dorbod 回复于 2016年01月07日 · 4907 次阅读

用户登录成功后页面链接

<li><%= link_to "信息修改", settings_user_path(current_user) %></li>

来修改用户信息。

route 里面这样定义:

# 用户
resources :users do 
  member do
    get :settings
  end
end

执行 bundle exec rake routes 后结果如下:

settings_user GET    /users/:id/settings(.:format)           users#settings
                       POST   /users/:id/settings(.:format)           users#settings
                 users GET    /users(.:format)                        users#index
                       POST   /users(.:format)                        users#create
              new_user GET    /users/new(.:format)                    users#new
             edit_user GET    /users/:id/edit(.:format)               users#edit
                  user GET    /users/:id(.:format)                    users#show
                       PATCH  /users/:id(.:format)                    users#update
                       PUT    /users/:id(.:format)                    users#update
                       DELETE /users/:id(.:format)                    users#destroy

views/user/settings.html.erb 里面核心代码截取如下:

<div style="display:block " id="basic" class="column two-thirds">
  <%= form_for(@user, url:settings_user_path(params[:id])) do |f| %>
  <%=render 'shared/error_messages', object: f.object %>
  <%= f.label :gender, '性别' %>
  <%= f.select :gender, ['female','male','others'] %>
  <%= f.label :age %>
  <%= f.text_field :age %>
  <%= f.label :height, '身高(如:175)' %>
  <%= f.text_field :height %>
  <%= f.label :hometown %>
  <%= f.text_field :hometown %>
  <%= f.label :constellation, '星座' %>
  <%= f.text_field :constellation %>
  <%= f.submit "Save changes", class: "btn btn-large btn-primary" %>
  <% end %>
</div>

users_controller 里面 settings 方法是这样的:

def settings

    @user = User.find_by_id(params[:id])

    if @user.update_attributes(basic_params)
      flash[:success] = "基本信息更新成功"
    elsif @user.update_attributes(accounts_params)
      flash[:success] = "账户信息更新成功"
    elsif @user.update_attributes(loved_params)
      flash[:success] = "恋爱信息更新成功"
    elsif @user.update_attributes(biography_params)
      flash[:success] = "背景信息更新成功"
    else
     render 'root'
    end
  end

users_controller 里面参数定义截取如下:

private
  def basic_params
   params.require(:user).permit(:gender, :age, :height, :hometown, :constellation)
  end

但我点击链接

<li><%= link_to "信息修改", settings_user_path(current_user) %></li>

后报错:param is missing or the value is empty: user,如果 settings 方法体删除掉就不会报这个错。 参考 stack overflow 一篇文章的意思是我的 settings action 不起作用:http://stackoverflow.com/questions/31299920/rails-param-is-missing-or-the-value-is-empty-user 可是我还是不理解是哪里的错误。

param is missing or the value is empty: user 也就是说你 view 传给 controller 的 params 里面没有 user 你可以检查下 view 生成的代码, 也可以检查下 controller 收到的 params 然后定位下问题.

#2 楼 @hging stack overflow 那个解释是这样的:

passreset_user_path(@user)doesn't "pass in" user to the method in question, it generates a URL. The URL will include an ID segment. It will look something like this:

/users/123/passreset

Your action will be invoked with the ID segment available in params[:id]. It's up to you to find the corresponding user in the database.

Instead of relying on params[:user], you need to do something along the lines of

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

The larger issue is that your passreset action makes no sense. It appears to be setup to receive a POST request containing new attributes for the user, but you're linking to it with a button that will produce a GET request with no payload of user attributes.

You're missing an entire intermediate step, where you show the user a password reset form. Your first request needs to serve that form up, and then that form can POST back to your passreset method.

你的路由代码怎么得出这个的?路由代码全贴出来

settings_user GET    /users/:id/settings(.:format)           users#settings
                         POST   /users/:id/settings(.:format)           users#settings

出错的日志不全,全贴出来

#4 楼 @nowherekai 路由代码:

                 Prefix Verb   URI Pattern                             Controller#Action
                   root GET    /                                       static_pages#home
                   help GET    /help(.:format)                         static_pages#help
                  about GET    /about(.:format)                        static_pages#about
                contact GET    /contact(.:format)                      static_pages#contact
                 signup GET    /signup(.:format)                       users#new
                  login GET    /login(.:format)                        sessions#new
                        POST   /login(.:format)                        sessions#create
                 logout DELETE /logout(.:format)                       sessions#destroy
         following_user GET    /users/:id/following(.:format)          users#following
         followers_user GET    /users/:id/followers(.:format)          users#followers
          settings_user GET    /users/:id/settings(.:format)           users#settings
                   user GET    /users/:id(.:format)                    users#update
                  users GET    /users(.:format)                        users#index
                        POST   /users(.:format)                        users#create
               new_user GET    /users/new(.:format)                    users#new
              edit_user GET    /users/:id/edit(.:format)               users#edit
                        GET    /users/:id(.:format)                    users#show
                        PATCH  /users/:id(.:format)                    users#update
                        PUT    /users/:id(.:format)                    users#update
                        DELETE /users/:id(.:format)                    users#destroy
edit_account_activation GET    /account_activations/:id/edit(.:format) account_activations#edit
        password_resets POST   /password_resets(.:format)              password_resets#create
     new_password_reset GET    /password_resets/new(.:format)          password_resets#new
    edit_password_reset GET    /password_resets/:id/edit(.:format)     password_resets#edit
         password_reset PATCH  /password_resets/:id(.:format)          password_resets#update
                        PUT    /password_resets/:id(.:format)          password_resets#update
             microposts POST   /microposts(.:format)                   microposts#create
              micropost DELETE /microposts/:id(.:format)               microposts#destroy
          relationships POST   /relationships(.:format)                relationships#create
           relationship DELETE /relationships/:id(.:format)            relationships#destroy

日志文件:

Started GET "/users/1/settings" for 127.0.0.1 at 2016-01-07 20:19:19 +0800
Processing by UsersController#settings as HTML
  Parameters: {"id"=>"1"}
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", 1]]
Completed 400 Bad Request in 1ms

ActionController::ParameterMissing (param is missing or the value is empty: user):
  app/controllers/users_controller.rb:102:in `basic_params'
  app/controllers/users_controller.rb:41:in `settings'


  Rendered /home/deu/.rvm/gems/ruby-2.1.5/gems/web-console-2.0.0.beta3/lib/action_dispatch/templates/rescues/_source.erb (10.8ms)
  Rendered /home/deu/.rvm/gems/ruby-2.1.5/gems/web-console-2.0.0.beta3/lib/action_dispatch/templates/rescues/_trace.html.erb (3.6ms)
  Rendered /home/deu/.rvm/gems/ruby-2.1.5/gems/web-console-2.0.0.beta3/lib/action_dispatch/templates/rescues/_request_and_response.html.erb (1.0ms)
  Rendered /home/deu/.rvm/gems/ruby-2.1.5/gems/web-console-2.0.0.beta3/lib/action_dispatch/templates/rescues/_web_console.html.erb (1.0ms)
  Rendered /home/deu/.rvm/gems/ruby-2.1.5/gems/web-console-2.0.0.beta3/lib/action_dispatch/templates/rescues/diagnostics.html.erb within rescues/layout (30.4ms)


路由写错了,把你 config/route.rb 代码贴出来。 你的 users_controller 的 settings 方法即处理 get 请求,又处理 post 请求,自然会报错了。 点击 <li><%= link_to "信息修改", settings_user_path(current_user) %></li> 链接,经过路由后,到达 settings 这个 action,这时候又不是提交的表单, basic_params 函数里面的 params.require(:user) 没有 :user 参数,报错。

#6 楼 @nowherekai

Rails.application.routes.draw do
  # get 'password_resets/new'

  # get 'password_resets/edit'

  # get 'sessions/new'

  # get 'users/new'

  root               'static_pages#home'
  get 'help'       =>'static_pages#help'
  get 'about'      =>'static_pages#about' 
  get 'contact'    =>'static_pages#contact'
  get 'signup'     =>'users#new'
  get 'login'      =>'sessions#new'
  post 'login'     =>'sessions#create'
  delete 'logout'  =>'sessions#destroy'

  # 用户
  resources :users do 
    member do
      get :following, :followers, :settings
    end
  end


  resources :account_activations, only: [:edit] # 账号激活
  resources :password_resets, only: [:new, :create, :edit, :update]
  resources :microposts, only:[:create, :destroy]
  resources :relationships, only:[:create, :destroy]
end

大神请指教

我又仔细看了一下你的 settings 方法,你写的有点问题,不能

if @user.update_attributes(basic_params)
    ...
 elsif @user.update_attributes(accounts_params)
    ...

这样写的。先不管你的 accounts,loved 那几个的更新,咱们先这看 basic_params 这一个。 你想做的是点击连接,显示更改设置的表单,然后提交表单后,进行更改操作。和 rails 常用的 edit 和 update 一样,你需要两个 action。 config/route.rb

resources :users do
  member do
      get :settings 
     post :update_settings
  end
end

user_controller.rb

def settings
  @user = User.find params[:id]
end
def update_settings
  @user = User.find_by_id(params[:id])

    if @user.update_attributes(basic_params)
       redirect_to ...
    else
       render :settings
   end
end

form_for 中的 url 也需做相应修改。

#8 楼 @nowherekai 谢谢前辈,这下我对网络路由这块懂了。至于说 accounts,loved 那几个更新,我就超链接多个页面好了。

10楼 已删除
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册