CarrierWave:指向现有图像

6
在我的Rails应用程序中,我使用Carrierwave将图片上传到Amazon S3。我想要指向现有的Amazon S3图像,而不必重新上传图像。例如,如果我在http://test.s3.amazonaws.com/image/path/0001/image.jpg有一个现有的Amazon S3图像,我能否更新图像的路径以指向此图像?我不想使用远程上传选项,因为我真的只想使用已经存在的完全相同的图像(但将其保存在我的记录的“路径”属性中)。
在控制台中,我尝试过:
image.update_attributes(:path=> "http://test.s3.amazonaws.com/image/path/0001/image.jpg")

但这无法覆盖图像的路径。

你是如何解决这个问题的? - Mohamad
最终我没有创建新的记录,而是指向了原始记录。 - scientiffic
嗨@scientiffic,你找到解决方案了吗?我非常感兴趣。 - medBouzid
4个回答

5

稍晚参与,总比不参与好!注意:这是针对Rails 4的,目前我正在测试Rails 4.1。

我认为这比应该做的更难!之所以这对我非常重要,是因为我正在附加100MB以上的MP3文件,由于CloudFlare SSL限制(和常识),我无法在我的主机上接收它们。幸运的是,AWS支持预授权上传,并且我让carrierwave为我做了正确的事情:

步骤1:让carrierwave告诉我如果可以存储文件,它会将其存储在哪里:

 m.raw_write_attribute('file','file.mp3');
 url = m.file.url
 signed = aws_presigned_url(url)

raw_write_attribute不会保存任何东西,它只是在设置值时绕过了CarrierWave。这使得对象表现得好像从数据库中读取了'file.mp3'。然后你可以问CarrierWave“文件在哪里”。然后我直接从客户端上传文件到S3。完成后,我再向Rails发出另一个API调用,执行以下代码:

 m.raw_write_attribute('file','file.mp3');
 m.update_attribute('file','file.mp3');

这两个配对的代码可以绕过Carrierwave。第一个让carrierwave认为“文件”列设置为“file.mp3”,第二个明确告诉rails将“file.mp3”持久化到数据库中。由于raw_write_attribute的调用,Carrierwave允许第二个代码通过而不进行更改。


3
在我的情况下,update_columnupdate_columns都非常好用:
model.update_columns file_1: 'filename.txt'

使用逗号更新列:

model.update_column :file_1, 'filename.txt'

这将不会执行任何回调并将列设置为 filename.txt

当我执行model.file_1.url时,我会得到正确的S3 URL。


2

据我所知,这并不会将值保存到数据库中,甚至不允许您使用@image.save将其写入数据库,因为就模型而言,没有任何需要保存的内容! - Daniel

1

我发现你实际上可以这样做,例如如果你的mount_uploader:path,那么:

image.remote_path_url = "http://test.s3.amazonaws.com/image/path/0001/image.jpg"
image.save

2
感谢您的回复。正如我在原帖中提到的,我不想重新上传文件,我相信这就是您使用remote_path_url和save所做的事情。 - scientiffic
你不想重新上传文件的原因是什么?在我的情况下,它将替换现有的文件,这仍然比从本地机器上传要快。不幸的是,我没有看到除了这种方法以外的其他载体波方式。 - shinnc
我发现重新上传文件对我的应用程序来说太慢了。相反,我只是检测新记录是否指向另一个图像,并在视图中替换图像(而不是在我的数据库中)。 - scientiffic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接