我已经安装了RailsTutorial示例应用程序(类似应用程序的推特),并且我试图理解为什么当我尝试更新用户数据库时,下面的控制台代码不会更新数据库。我希望在使用user.save
后,用户信息会得到更新。但是,这会回滚到未经编辑的数据。这是由于基于用户的限制吗?
用户控制器:
class UsersController < ApplicationController
#before_filter :signed_in_user, only: [:index, :edit, :update, :destroy, :following, :followers]
# By default before filters apply to all actions
#before_filter :correct_user, only: [:edit, :update]
def edit
@user = User.find(params[:id])
end
def update
@user = User.find params[:id]
respond_to do |format|
if @user.update_attributes(params[:user])
flash[:notice] = "Profile updated"
format.html { redirect_to(@user, :notice => 'User was successfully updated.') }
format.json { respond_with_bip(@user) }
else
format.html { render :action => "edit" }
format.json { respond_with_bip(@user) }
end
end
end
private
def correct_user
@user = User.find(params[:id])
redirect_to(root_path) unless current_user?(@user)
end
def admin_user
redirect_to(root_path) unless current_user.admin?
end
end
Rails控制台:
1.9.3-p392 :001 > user = User.find(109)
User Load (8.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 109]]
=> #<User id: 109, name: "laurie", email: "auriepage@gmail.com", created_at: "2013-09-26 18:10:12", updated_at: "2013-09-26 18:10:12", password_digest: "$2a$10$aXEtun8Z2Deqy2wNxvFRNOjPczKQkYc1vDezP5OduJuF...", remember_token: "YhIUhgFm9iMewxdNOHJ45A", admin: false>
1.9.3-p392 :002 > user.name = "larry"
=> "larry"
1.9.3-p392 :003 > user.save
(0.2ms) begin transaction
User Exists (0.6ms) SELECT 1 AS one FROM "users" WHERE (LOWER("users"."email") = LOWER('auriepage@gmail.com') AND "users"."id" != 109) LIMIT 1
(0.1ms) rollback transaction
=> false
用户模型:
class User < ActiveRecord::Base
# Declaration of public variables
attr_accessible :email, :name, :password, :password_confirmation
has_secure_password
has_many :microposts, dependent: :destroy
has_many :relationships, foreign_key: "follower_id", dependent: :destroy
has_many :followed_users, through: :relationships, source: :followed
has_many :reverse_relationships, foreign_key: "followed_id", class_name: "Relationship", dependent: :destroy
has_many :followers, through: :reverse_relationships, source: :follower
before_save {email.downcase!}
before_save :create_remember_token
validates :name, presence: true, length: {maximum: 50}
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, format: {with: VALID_EMAIL_REGEX}, uniqueness: {case_sensitive: false}
validates :password, presence: true, length: {minimum: 6}
validates :password_confirmation, presence: true
after_validation {self.errors.messages.delete(:password_digest)}
private
def create_remember_token
self.remember_token = SecureRandom.urlsafe_base64
end
end
答案 0 :(得分:126)
您的用户模型可能包含不满足的验证。由于你没有发布那些我无法真正解决你的问题。为了简化实际操作,您可以调试用户不愿意保存的原因。
尝试运行
user.errors.full_messages
应该会给你一个提示是什么问题。
答案 1 :(得分:16)
我知道这是一篇旧帖子,但希望这有助于将来有人通过本教程。
如接受的答案所示,这是由于未得到满足的验证。我也遇到了这个问题,并发现另一种解决方法是在update_attribute
对象上使用user
方法。例如,如果要更新name
对象的user
字段并将其自动保存到数据库,则无需触摸虚拟password
和password_confirmation
字段,使用以下内容:
user.update_attribute(:name, "larry")
这将仅更新name
字段并将其保存到数据库(无需调用save
方法),而无需触及password
和password_confirmation
字段。
答案 2 :(得分:7)
尝试保存或验证活动记录模型实例后,您可以查看有关一些有用命令的更多信息。
user = User.find(108)
user.name = "Larry"
user.valid? # returns false
user.errors.messages # returns something like {email: "Cant be blank"}
显然我犯了这个错误,因为我不知道你的模型文件是什么样的,但是如果它的角色通常是由于两个原因之一。首先是您的验证失败。如果它们没有错误消息,可能是因为过滤器链中的某些内容返回false。例如
class User << ActiveRecord::Base
before_save :accidentally_return_false
def accidentally_return_false
self.some_boolean = (condition == value)
end
end
user = User.new( params )
user.save # where condition does not equal value
user.valid? # false because of the before save method
希望有所帮助
答案 3 :(得分:5)
保存回滚时,请使用保存!相反,将打印错误日志。
答案 4 :(得分:3)
您的验证未通过。你可以这样做:
user.errors.full_messages
保存失败后在控制台中查看原因。
答案 5 :(得分:2)
我遇到了同样的问题,没有存储任何错误。事实证明我的before_save
函数返回false导致保存被取消(我猜?我是铁杆新手)。
我试图设置一个布尔值,该布尔值只能在文件上传后设置。
这是我正在做的事情:
before_save :set_orientation
def set_orientation
# ...do stuff...
self[:is_landscape] = ratio > 1 # stores AND returns the boolean value!!
end
函数的最后一行也是一个隐含的返回,我不是故意做的。我的解决方案是明确地做出回报:
before_save :set_orientation
def set_orientation
# ...do stuff...
self[:is_landscape] = ratio > 1 # store the boolean value
return # now return
end
答案 6 :(得分:0)
当我尝试更新用户的admin属性时,我遇到了同样的问题,即数据库在控制台中回滚我的事务。如果您正在进行Hartl rails教程,问题是如果您在控制台中键入user.errors.messages,它将告诉您密码太短。这是因为在模型中存在密码验证,然后将密码保存并密码到password_digest中。
解决此问题的方法是在控制台中执行正常活动,例如设置user.admin = true,然后在完成后输入user.password =&#34; foobar&#34;,然后输入user.password_confirmation =&#34; foobar&#34;,然后当你执行user.save时,它将提交你所有的更改。
答案 7 :(得分:0)
尝试更新数据库:
rails db:migrate
答案 8 :(得分:0)
以防万一将来对某人有所帮助-我遇到了类似的问题,导致回滚的原因是我的数据没有通过验证(在发现问题后实施了验证)。手动更正数据即可解决问题。