要停用帐户,我的方法类似于:
def closing # Controller method
@user = current_user
relationships = @user.relationships
relationships.each { |relationship| relationship.destroy }
log_out
end
def log_out # In sessions helper
forget(current_user)
session.delete(:user_id)
@current_user = nil
end
def forget(user) # In sessions helper
debugger
user.forget # If I change this to user.reload.forget the error below is gone
cookies.delete(:user_id)
cookies.delete(:api_token)
end
def forget # In User table
update_attributes(remember_digest: nil, email_digest: nil)
end
但是,关闭帐户会为行user.forget
生成错误消息:
ActiveRecord :: RecordNotFound:无法找到与之关系 ' id' = 129095216 [地点"人际关系"。" user_id" =?]
在上面的代码中查看debugger
的位置。我使用调试器查看user
的值:字段default_relationship_id
仍然具有值129095216
。如果我输入user.reload
,则default_relationship_id
的值确实为nil
。事实上,将会话助手中的那一行重写为user.reload.forget
,一切正常。
然而,重新加载不是必要的。事实上,在过去它曾经工作过,我一直在改变一些代码,但不了解这些行为。一定有什么问题,因为重新加载不是必要的。该怎么办?是什么导致了这种行为?
有关该关联的更多信息(从上述错误出现之后,此代码未进行任何更改):
用户模型:
has_many :relationships, dependent: :destroy, inverse_of: :user
has_many :organizations, through: :relationships, inverse_of: :users
belongs_to :default_relationship, class_name: "Relationship", foreign_key: :default_relationship_id, inverse_of: :default_for_user
has_one :default_organization, through: :default_relationship, source: :organization
关系模型:
belongs_to :user, :inverse_of => :relationships
belongs_to :organization, :inverse_of => :relationships
has_one :default_for_user, class_name: "User", foreign_key: :default_relationship_id, inverse_of: :default_relationship, dependent: :nullify
答案 0 :(得分:1)
尝试删除存储在会话中的cookie和/或值是一种有缺陷的方法。相反,您应该使用reset_session
- 它使当前会话标识符无效并发出新标识符。
def log_out # In sessions helper
reset_session
@current_user = nil
end
因此,即使用户仍然有一个指向其先前会话的cookie,Rails也不会加载会话。
@user = current_user
relationships = @user.relationships
relationships.each { |relationship| relationship.destroy }
请注意,在此代码中,您在User
中存储@user
对象,在ActiveRecord::Relation
中存储relationships
对象 - 这些对象都存储在服务器内存中。当您遍历relationships
并销毁每个时,您不会更新@user
中存储在内存中的值。这就是为什么需要.reload
- 它用数据库中的表示刷新过时的@user
对象。
相反,您应该使用destroy_all
,因为它会产生更有效的数据库查询,并且使用的内存少于迭代每个项目。
def closing # Controller method
@user = current_user
@user.relationships.destroy_all
@user = @user.reload
end