新手问题 我想尝试用 admin 去修改其他 User 的部分信息时遇到一些问题

woody1983 · 2012年12月12日 · 最后由 upsilon2gamma 回复于 2012年12月18日 · 3709 次阅读
# PUT /users/1
# PUT /users/1.json
def update
  @user = User.find(params[:id])

  respond_to do |format|
    if current_user.admin?
      @user.update_attributes(:name => params[:name])
    else
      if @user.update_attributes(params[:user])
        format.html { redirect_to @user, notice: 'User was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end
end

update 动作有走这层过滤

def correct_user
  @user = User.find(params[:id])
  redirect_to(users_path) unless current_user?(@user) || current_user.admin?
end

问题是现在提交编辑后 报 HTTP 406 错误

HTTP 错误 406 406 不可接受 根据此请求中所发送的“接受”标题,此请求所标识的资源只能生成内容特征为“不可接受”的响应实体。 如果问题依然存在,请与服务器的管理员联系。

这个是干吗的?

def correct_user

#1 楼 @guyanbiao 判断是否是当前拥护 禁止 user1 想 user2 PUT 数据

我在 console 里也试过了 还是不行 报密码不能为空。我就是想通过 admin 来修改一部分其他 user 的属性

你的错误是因为 @user.update_attributes(params[:user]) 这一句搞的鬼!这一句会产生验证,就是 user 这个 model 中的验证,你的验证中有包含密码的验证。 Updates the attributes of the model from the passed-in hash and saves the record, all wrapped in a transaction. If the object is invalid, the saving will fail and false will be returned.

在更新之前

params[:user].delete(:password)
params[:user].delete(:password_confirmation)

@user.update_attributes(params[:user], :validate => false)

validates :password, :if => :new_record?

#6 楼 @woaigithub :validate => false) 这个好像不起作用

ActiveModel::MassAssignmentSecurity::Error in UsersController#update

Can't mass-assign protected attributes: validate

其他的呢? 对不起,我没有验证,但是我写过 save(:validate => false)

#9 楼 @woaigithub 矮油~ 没事 我这个是初学者的疑问 呵呵 我换个方法试试

#9 楼 @woaigithub 感谢感谢 搞定了 一开始没有参透你的禅机 😄

urrent_user.admin?
          @user.attributes = (params[:user]) #绕开验证
          if @user.save( :validate => false )

#11 楼 @woody1983 是不是可以跳过验证,这个还要看你的需要。

报密码不能为空可能是你有一个虚拟的 password 属性。比如你用了什么 auth 类的 gem,或者你自己加了一个attr_accessor :password。然后又有validates :password这样的验证。那么,当你是从数据库中取出记录User.find(params[:id])的时候,这个属性还是nil。你只修改 name 的话,就会报 invalid 了。 我觉得绕开验证不是好的方法。那个实际只是掩盖问题,不是解决问题。validates :password, :if => :new_record?更妥当。 另外,既然在 filter 里有了@user = User.find(params[:id]),action 里的第一句就多余了。 我就是搞不懂怎么会有 406。admin 修改用户后,没有format.html这样的语句是不是会导致 406?

#13 楼 @upsilon2gamma 这个如果有前提的话是不存在掩盖的 比如 user 注册完以后 有些栏位和内容 应该是只有 admin 或 HR 这样身份的人才可以修改或赋值 比如部门 title 之类的。

#14 楼 @woody1983 如果你仅仅想绕开验证,可以使用 update_column 代替 update_attributes。但是慎用!

#15 楼 @zlx_star 嗯~我在写 Rspec 去测 确保只有 admin 身份的 User 才有资格绕开验证

#14 楼 @woody1983 你没有理解我的意思。我不是说你修改user本身有什么问题。而是你现在处理的方法(绕开验证)不妥当,只是把问题藏起来,“看上去”没有问题了(程序能跑了)。 正像你自己说的,修改某些字段是一个常见的情况。那与其每次都绕过验证,不如把问题找出来,解决好。 我猜测问题是有虚拟的password属性,然后又在上面加了validation,所以当从数据库取出数据后,实例化的user还没有设置这个值,导致你save/update的时候无法通过验证。你可以试试在action里加上logger.debug(@user.errors.full_messages),然后看看后台输出是不是有password cannot be blank之类的信息。如果是这样#7 楼 的方法其实比你现在绕过验证要好很多。因为以后遇到其他需要修改某些字段的时候也一样可以避免这个问题。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号