如何解决从PDF读取文本可在Rails控制台中使用,但不能在Rails应用程序中使用
我有一个简单的一页可搜索PDF,可以使用Active Storage上传到Rails 6应用程序模型(Car)。我可以使用Rails控制台中的“ tempfile”和“ pdf-reader” gem从PDF提取文本:
> @car.creport.attached?
=> true
> f = Tempfile.new(['file','.pdf'])
> f.binmode
> f.write(@car.creport.blob.download)
> r = PDF::Reader.new(f.path.to_s)
> r.pages[1].text
=> "Welcome to the ABC Car Report for January 16,20...
但是,如果我在cars_controller.rb的create方法中尝试相同的操作,则它将无效:
# cars_controller.rb
...
def create
@car = Car.new(car_params)
@car.filetext = ""
f = Tempfile.new(['file','.pdf'])
f.binmode
f.write(@car.creport.blob.download)
r = PDF::Reader.new(f.path.to_s)
@car.filetext = r.pages[1].text
...
end
运行Rails应用程序时,我可以创建一个新的Car并选择要附加的PDF文件。但是,当我单击“提交”时,在f.write()行的cars_controller.rb中得到了FileNotFoundError。
我的直觉是,控制器试图读取blob以便过早地将其写入temp文件(即,甚至尚未写入blob之前)。我尝试插入一个sleep(2)
来给它时间,但是我得到了相同的FileNotFoundError。
有什么想法吗?
谢谢!
解决方法
我不明白为什么你要跳这么多圈。并使用.download
而不加阻塞将整个文件加载到内存中(像样)。如果@car.creport
是ActiveStorage附件,则可以改用open method:
@car.creport.blob.open do |file|
file.binmode
r = PDF::Reader.new(file) # just pass the IO object
@car.filetext = r.pages[1].text
end if @car.creport
这会将文件蒸到磁盘上(作为临时文件)。
如果您只是通过普通的旧文件输入进行文件输入,您将在参数中得到一个ActionDispatch::Http::UploadedFile,这也非常容易打开:
params[:file].open do |file|
file.binmode
r = PDF::Reader.new(file) # just pass the IO object
@car.filetext = r.pages[1].text
end if params[:file].respond_to?(:open)
,
区别似乎与您的@car
变量一样。
在控制台中,您已附加了一个Blob(@car.creport.attached? => true
)。在您的控制器中,您正在初始化Car类的新实例,因此,除非进行一些初始化工作以在后台附加某些内容,否则它将为nil。
我不确定为什么会返回“找不到文件”错误,但是从我所看到的那是代码示例之间的唯一区别。您正在尝试编写@car.creport.blob.download
,它存在于控制台的@car
中,但在控制器中为空。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。