微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从PDF读取文本可在Rails控制台中使用,但不能在Rails应用程序中使用

如何解决从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 举报,一经查实,本站将立刻删除。