【问题标题】:update_attributes failing when I try to update an attribute当我尝试更新属性时 update_attributes 失败
【发布时间】:2015-09-13 03:48:11
【问题描述】:

我有一个用户数据库作为 User(id: integer, username: string, created_at: datetime, updated_at: datetime, password_digest: string, admin: boolean, usermanager: boolean)。 我想更新一个用户并使他成为管理员,将 admin 变量设置为 true。

我在控制器中的更新:

def update
@user = User.find(params[:id])
if @user.update_attributes(user_params)
  flash[:success] = "User edited"
  redirect_to current_user
else
  render users_url
end
end

update_attributes 在所有情况下都失败。我打开了一个调试器并尝试调用 update_attributes,它在那里也失败了。

(byebug) user_params = {"admin"=>true}
{"admin"=>true}
(byebug) @user
#<User id: 1, username: "dsmegha", created_at: "2015-09-11 07:42:01", updated_at: "2015-09-13 03:25:01", password_digest: "$2a$10$BInH6J1dXHanqNIdGag6megSyrmm95AmjTEGPemNdGU...", admin: false, usermanager: nil>
(byebug) @user.update_attributes(user_params)
   (0.2ms)  begin transaction
  User Exists (0.2ms)  SELECT  1 AS one FROM "users" WHERE ("users"."username" = 'dsmegha' AND "users"."id" != 1) LIMIT 1
   (0.2ms)  rollback transaction
false

update_attribute 同样适用。

(byebug) @user.update_attribute(:admin,true)
   (0.2ms)  begin transaction
   (0.1ms)  commit transaction
true
(byebug) @user
#<User id: 1, username: "dsmegha", created_at: "2015-09-11 07:42:01", updated_at: "2015-09-13 03:25:01", password_digest: "$2a$10$BInH6J1dXHanqNIdGag6megSyrmm95AmjTEGPemNdGU...", admin: true, usermanager: nil>
(byebug)

知道我在这里缺少什么吗?

【问题讨论】:

  • user_params 中允许使用哪些参数?
  • private def user_params params.require(:user).permit(:username, :password, :password_confirmation, :admin) end.
  • 有验证吗?
  • has_many :timezones,dependent: :destroy VALID_USERNAME_REGEX = /\A[a-zA-Z0-9]+\z/ 验证 :username, presence: true, length: { minimum:6, maximum :15 },格式:{ with:VALID_USERNAME_REGEX },唯一性:true 验证:password,存在:true,长度:{ minimum:6,maximum:15 } has_secure_password 不适用于 :admin 字段
  • 如果您只更新admin 字段,请尝试@user.update_column(:admin, true)。检查它是否有效。

标签: mysql ruby-on-rails


【解决方案1】:

也许我认为当前用户数据无效。请查看user.errors

示例)

用户.rb

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable,:confirmable,
         :recoverable, :rememberable, :trackable, :validatable, :lockable

  validates :name, presence: true
end

 pry(main)> user = User.last
=> #<User:0x007fe328fe56d8
 id: 3,
 email: "hogehoge@example.com",
 name: "",
 encrypted_password: "$2a$10$I.xXo0AtAz8nuCUzOGclPe6PA//XMZtjW6fh94D1t25jb7eV9bsS.",
 current_sign_in_at: Tue, 02 Jun 2015 01:53:08 JST +09:00,
 last_sign_in_at: Tue, 02 Jun 2015 01:52:20 JST +09:00,
 current_sign_in_ip: "127.0.0.1",
 last_sign_in_ip: "127.0.0.1",
 created_at: Tue, 02 Jun 2015 01:49:40 JST +09:00,
 updated_at: Sun, 13 Sep 2015 13:16:26 JST +09:00,
 confirmation_token: nil,
 confirmed_at: Tue, 02 Jun 2015 01:52:01 JST +09:00,
 confirmation_sent_at: Tue, 02 Jun 2015 01:49:40 JST +09:00,
 unconfirmed_email: nil,
 failed_attempts: 0,
 unlock_token: nil,
 locked_at: nil,
 status: 1>

[7] pry(main)> user.update_attributes(status: 2)
   (0.1ms)
        BEGIN
   (0.2ms)
        ROLLBACK
=> false

[8] pry(main)> user.errors
=> #<ActiveModel::Errors:0x007fe328d893f8
 @base=
  #<User:0x007fe328fe56d8
   id: 3,
   email: "hogehoge@example.com",
   name: "",
   encrypted_password: "$2a$10$I.xXo0AtAz8nuCUzOGclPe6PA//XMZtjW6fh94D1t25jb7eV9bsS.",
   reset_password_token: "XWmjsEBujb2-aWd5YHYT",
   reset_password_sent_at: nil,
   remember_created_at: nil,
   sign_in_count: 2,
   current_sign_in_at: Tue, 02 Jun 2015 01:53:08 JST +09:00,
   last_sign_in_at: Tue, 02 Jun 2015 01:52:20 JST +09:00,
   current_sign_in_ip: "127.0.0.1",
   last_sign_in_ip: "127.0.0.1",
   created_at: Tue, 02 Jun 2015 01:49:40 JST +09:00,
   updated_at: Sun, 13 Sep 2015 13:16:26 JST +09:00,
   confirmation_token: nil,
   confirmed_at: Tue, 02 Jun 2015 01:52:01 JST +09:00,
   confirmation_sent_at: Tue, 02 Jun 2015 01:49:40 JST +09:00,
   unconfirmed_email: nil,
   failed_attempts: 0,
   unlock_token: nil,
   locked_at: nil,
   status: 2>,
 @messages={:name=>["can't be blank"]}>

另外写。

视图也许有密码输入字段?在这种情况下,我认为您需要在更新用户数据时删除密码参数。

这个怎么样?

用户.rb

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable,:confirmable,
         :recoverable, :rememberable, :trackable, :validatable, :lockable

  validates :name, presence: true

  def update_without_current_password(params, *options)
    params.delete(:current_password)

    if params[:password].blank?
      params.delete(:password)
      params.delete(:password_confirmation) if params[:password_confirmation].blank?
    end

    clean_up_passwords
    update_attributes(params, *options)
  end
end

控制器

def update
  @user = User.find(params[:id])
  if @user.update_without_current_password(user_params)
    flash[:success] = "User edited"
    redirect_to current_user
  else
    render users_url
  end
end

【讨论】:

  • 是的,似乎是这样。但是我正在使用 bcrypt,我的密码将为空,并且将创建 password_digest。使用 update_column 是解决这个问题的方法吗? #<:errors:0x007f57633c0c28 id: username: created_at: updated_at: :03 password_digest: admin: true usermanager:>, @messages={:password=>["不能为空", "太短(最少 6 个字符)"]}>
  • 也许我认为您需要在更新用户数据时删除密码参数。我写了添加答案。
猜你喜欢
  • 2014-01-11
  • 1970-01-01
  • 2021-12-03
  • 2016-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多