zar*_*tra 10 activerecord ruby-on-rails ruby-on-rails-5 rails-activestorage
我最近将我的项目升级到最新的Rails版本(5.2)以获得ActiveStorage- 一个处理附件上传到AWS S3,Google Cloud等云服务的库.
几乎一切都很好.我可以上传和附加图像
user.avatar.attach(params[:file])
Run Code Online (Sandbox Code Playgroud)
接收它
user.avatar.service_url
Run Code Online (Sandbox Code Playgroud)
但现在我想替换/更新用户的头像.我以为我可以跑
user.avatar.attach(params[:file])
Run Code Online (Sandbox Code Playgroud)
再次.但这会引发错误:
ActiveRecord::RecordNotSaved: Failed to remove the existing associated avatar_attachment. The record failed to save after its foreign key was set to nil.
Run Code Online (Sandbox Code Playgroud)
那是什么意思?如何更改用户头像?
Car*_*III 10
has_one模型和附件记录之间的关联会引发此错误.之所以会发生这种情况,是因为尝试用新的附件替换原始附件将孤立原始附件并导致它使belongs_to关联的外键约束失败.这是所有ActiveRecord has_one关系的行为(即它不是特定于ActiveStorage).
class User < ActiveRecord::Base
has_one :profile
end
class Profile < ActiveRecord::Base
belongs_to :user
end
# create a new user record
user = User.create!
# create a new associated profile record (has_one)
original_profile = user.create_profile!
# attempt to replace the original profile with a new one
user.create_profile!
=> ActiveRecord::RecordNotSaved: Failed to remove the existing associated profile. The record failed to save after its foreign key was set to nil.
Run Code Online (Sandbox Code Playgroud)
在尝试创建新配置文件时,ActiveRecord尝试user_id将原始配置文件设置为nil,这会使belongs_to记录的外键约束失败.我相信这实际上是当您尝试使用ActiveStorage将新文件附加到模型时发生的事情......这样做会尝试使原始附件记录的外键无效,这将失败.
has_one关系的解决方案是在尝试创建新记录之前销毁相关记录(即在尝试附加另一个记录之前清除附件).
user.avatar.purge # or user.avatar.purge_later
user.avatar.attach(params[:file])
Run Code Online (Sandbox Code Playgroud)
在尝试为has_one关系添加新记录时,ActiveStorage是否应该自动清除原始记录是一个不同的问题,最好对核心团队提出......
IMO让它与所有其他has_one关系一致工作是有道理的,并且可能最好让开发人员明确清除原始记录,然后再附加新记录而不是自动执行(这可能有点冒昧) ).
资源:
您可以在使用purge_later之前调用:attachhas_one_attached
user.avatar.purge_later
user.avatar.attach(params[:file])
Run Code Online (Sandbox Code Playgroud)
更新
Rails 现在自动清除以前的附件(自 8 月 29 日起)。
| 归档时间: |
|
| 查看次数: |
6435 次 |
| 最近记录: |