为什么在使用 form_for 时必须是 current_user 而不是 @user

why when using form_for it has to be current_user instead of @user

感谢您抽空前来。我有一个问题,我很困惑,但希望得到更好的理解。在我过去的项目中,我能够做到

<%= form_for @user, :html => { :multipart => true } do |f| %>
 <p class="editpage">Profile Picture: <%= f.file_field :avatar %></p>
 <%= f.submit %>
<% end %>

但在我当前的项目中。当我使用@user 时,它在我尝试上传图片时一直提示需要密码。我的用户控制器的私有参数中确实有 :password 和 :password_confirmation 。目前我想出的唯一上传图片的方法是

<%= form_for current_user, :html => { :multipart => true } do |f| %>
  <p class="editpage">Profile Picture: <%= f.file_field :avatar %></p>
  <%= f.submit "Upload" %>
<% end %>

谁能帮忙解释一下为什么会这样。我很高兴它以某种方式工作,但我想更好地理解为什么它需要 current_user 而不是 @user 因为我正在尝试更新用户信息。感谢您的所有帮助和解释。

在我的 ApplicationController 中添加了信息

helper_method :current_user


def current_user
 if session[:user_id]
  @current_user = User.find(session[:user_id])
 else
  @current_user = nil
 end
end

终端内出错

Started POST "/users" for 127.0.0.1 at 2015-08-25 02:04:55 +0900
Processing by UsersController#create as HTML
  Parameters: {"utf8"=>"✓",   "authenticity_token"=>"e3DrDAhJPV4vgma9tg7wk9g589ZRDNInynWlXDv7oJQ=", "user"=>  {"avatar"=>#<ActionDispatch::Http::UploadedFile:0x007f8784a00ec0 @tempfile=#  <Tempfile:/var/folders/83/2r02tq2d3934d30syfmpz9yw0000gn/T/RackMultipart20150825-  4587-14jh732>,   @original_filename="10920917_10152994488342090_418253413398867864_n.jpg",   @content_type="image/jpeg", @headers="Content-Disposition: form-data;   name=\"user[avatar]\";   filename=\"10920917_10152994488342090_418253413398867864_n.jpg\"\r\nContent-Type:   image/jpeg\r\n">}, "commit"=>"Upload"}
Command :: file -b --mime  '/var/folders/83/2r02tq2d3934d30syfmpz9yw0000gn/T/47a027085753557774697c8014ad69c7 20150825-4587-1ka91nc.jpg'
Command :: identify -format '%wx%h,%[exif:orientation]'  '/var/folders/83/2r02tq2d3934d30syfmpz9yw0000gn/T/47a027085753557774697c8014ad69c7 20150825-4587-1p9nueh.jpg[0]' 2>/dev/null
Command :: identify -format %m '/var/folders/83/2r02tq2d3934d30syfmpz9yw0000gn/T/47a027085753557774697c8014ad69c720150825-4587-1p9nueh.jpg[0]'
Command :: convert '/var/folders/83/2r02tq2d3934d30syfmpz9yw0000gn/T/47a027085753557774697c8014ad69c720150825-4587-1p9nueh.jpg[0]' -auto-orient -resize "200x200>" '/var/folders/83/2r02tq2d3934d30syfmpz9yw0000gn/T/47a027085753557774697c8014ad69c720150825-4587-1p9nueh20150825-4587-1alffdu'
Command :: file -b --mime '/var/folders/83/2r02tq2d3934d30syfmpz9yw0000gn/T/47a027085753557774697c8014ad69c720150825-4587-1p9nueh20150825-4587-1alffdu'
Command :: identify -format '%wx%h,%[exif:orientation]' '/var/folders/83/2r02tq2d3934d30syfmpz9yw0000gn/T/47a027085753557774697c8014ad69c720150825-4587-1p9nueh.jpg[0]' 2>/dev/null
Command :: identify -format %m '/var/folders/83/2r02tq2d3934d30syfmpz9yw0000gn/T/47a027085753557774697c8014ad69c720150825-4587-1p9nueh.jpg[0]'
Command :: convert '/var/folders/83/2r02tq2d3934d30syfmpz9yw0000gn/T/47a027085753557774697c8014ad69c720150825-4587-1p9nueh.jpg[0]' -auto-orient -resize "120x" -crop "120x120+0+20" +repage '/var/folders/83/2r02tq2d3934d30syfmpz9yw0000gn/T/47a027085753557774697c8014ad69c720150825-4587-1p9nueh20150825-4587-1kd13uh'
Command :: file -b --mime '/var/folders/83/2r02tq2d3934d30syfmpz9yw0000gn/T/47a027085753557774697c8014ad69c720150825-4587-1p9nueh20150825-4587-1kd13uh'
Command :: identify -format '%wx%h,%[exif:orientation]' '/var/folders/83/2r02tq2d3934d30syfmpz9yw0000gn/T/47a027085753557774697c8014ad69c720150825-4587-1p9nueh.jpg[0]' 2>/dev/null
Command :: identify -format %m '/var/folders/83/2r02tq2d3934d30syfmpz9yw0000gn/T/47a027085753557774697c8014ad69c720150825-4587-1p9nueh.jpg[0]'
Command :: convert '/var/folders/83/2r02tq2d3934d30syfmpz9yw0000gn/T/47a027085753557774697c8014ad69c720150825-4587-1p9nueh.jpg[0]' -auto-orient -resize "75x" -crop "75x75+0+12" +repage '/var/folders/83/2r02tq2d3934d30syfmpz9yw0000gn/T/47a027085753557774697c8014ad69c720150825-4587-1p9nueh20150825-4587-1recdb2'
Command :: file -b --mime '/var/folders/83/2r02tq2d3934d30syfmpz9yw0000gn/T/47a027085753557774697c8014ad69c720150825-4587-1p9nueh20150825-4587-1recdb2'
Command :: identify -format '%wx%h,%[exif:orientation]' '/var/folders/83/2r02tq2d3934d30syfmpz9yw0000gn/T/47a027085753557774697c8014ad69c720150825-4587-1p9nueh.jpg[0]' 2>/dev/null
Command :: identify -format %m '/var/folders/83/2r02tq2d3934d30syfmpz9yw0000gn/T/47a027085753557774697c8014ad69c720150825-4587-1p9nueh.jpg[0]'
Command :: convert '/var/folders/83/2r02tq2d3934d30syfmpz9yw0000gn/T/47a027085753557774697c8014ad69c720150825-4587-1p9nueh.jpg[0]' -auto-orient '/var/folders/83/2r02tq2d3934d30syfmpz9yw0000gn/T/47a027085753557774697c8014ad69c720150825-4587-1p9nueh20150825-4587-1vsru58'
Command :: file -b --mime '/var/folders/83/2r02tq2d3934d30syfmpz9yw0000gn/T/47a027085753557774697c8014ad69c720150825-4587-1p9nueh20150825-4587-1vsru58'
   (0.4ms)  begin transaction
   Command :: file -b --mime '/var/folders/83/2r02tq2d3934d30syfmpz9yw0000gn/T/47a027085753557774697c8014ad69c720150825-4587-1ksrnek.jpg'
   (0.1ms)  rollback transaction
Redirected to http://localhost:3000/
Completed 302 Found in 625ms (ActiveRecord: 0.5ms)

**用户控制器*

class UsersController < ApplicationController
 def index
  @user = User.new
  @users = User.all
  # if current_user
  #   @leaders = @current_user.leaders
  # end
 end

 def create
  @user = User.new(user_params)
  if @user.save
   session[:user_id] = @user.id
   cookies[:user_id] = @user.id
   flash[:notice] = "Successfully Registerd"
   redirect_to "/"
  else
   flash[:alert] = @user.errors.full_messages
   redirect_to "/"
  end
 end

 def new
  @user = User.new
 end

 def edit
  @user = User.friendly.find(params[:id])
  current_user
 end

 def show
  @user = User.friendly.find(params[:id])
  current_user
  # if @current_user
  #    @followerlink = Follow.where(leader_id: @user.id,
  #                               follower_id: @current_user.id).first
  # end
 end

 def update
  @user = User.friendly.find(params[:id])
  if @user.update(user_params)
    flash[:notice] = "You have successfully update your information"
    redirect_to "/"
  end
 end

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


 def user_params
  params.require(:user).permit(:background, :username_or_email, :first_name,   :last_name, :email, :password, :password_confirmation, :user_name, :avatar)
 end
end

用户模型

class User < ActiveRecord::Base

  extend FriendlyId
  friendly_id :user_name, use: :slugged

  has_many :conversations, :foreign_key => :sender_id
  after_create :create_default_conversation

  has_attached_file :avatar, :styles => {
   :medium => "200x200>",
   :small => "120x120#",
   :thumb => "75x75#",
   :default_url => "http://www.adtechnology.co.uk/images/UGM-default-user.png"
  }

  validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/

  has_attached_file :background, :styles => {
   :medium => "200x200>",
   :small => "120x120#",
   :thumb => "75x75#",
   :default_url => "http://www.adtechnology.co.uk/images/UGM-default-user.png"
  }

  validates_attachment_content_type :background, :content_type =>   /\Aimage\/.*\Z/

  validates :password, presence: true, on: :create

end

您正在使用此表单创建用户。

Processing by UsersController#create as HTML

既然你只是想添加一个头像,那么你的目标是进行更新。您需要指定要向服务器发出的请求类型,因此请在表单中添加 :method => :PUT

<%= form_for @user, :method => :PUT , :html => { :multipart => true }  do |f| %

此外,您需要在任何有密码的地方使用 has_secure_password 方法。Read about it here。很高兴知道它是什么以及它的作用。

has_secure_password 
validates :password, presence: true, allow_nil: true 

我添加了一个allow_nil: true,这样你就可以更新而不需要指定密码。

调试变量发生的情况的一种方法是使用 inspect

例如:

  @user.inspect
  current_user.inspect

如果你想看看你的模型有什么样的属性,你也可以使用它:

User.inspect

您正在尝试使用似乎缺乏适当验证的参数创建新用户,因此提交正在回滚。

您的用户模型需要密码才能创建新用户:

validates :password, presence: true, on: :create

但是,您的失败请求(来自您发布的终端错误)没有传递密码:

Parameters: {"utf8"=>"✓",   "authenticity_token"=>"e3DrDAhJPV4vgma9tg7wk9g589ZRDNInynWlXDv7oJQ=", "user"=>  {"avatar"=>#<ActionDispatch::Http::UploadedFile:0x007f8784a00ec0 @tempfile=#  <Tempfile:/var/folders/83/2r02tq2d3934d30syfmpz9yw0000gn/T/RackMultipart20150825-  4587-14jh732>,   @original_filename="10920917_10152994488342090_418253413398867864_n.jpg",   @content_type="image/jpeg", @headers="Content-Disposition: form-data;   name=\"user[avatar]\";   filename=\"10920917_10152994488342090_418253413398867864_n.jpg\"\r\nContent-Type:   image/jpeg\r\n">}, "commit"=>"Upload"}

如果您在控制器中修改新操作:

def 新 @user = User.new(密码:"some password") 结束

然后将@user 放入您的 form_for 调用中,它应该可以工作。

编辑: 我假设您正在寻找创建操作,但是,我认为 Hristo Georgiev 提供了正确的解决方案。