Rails ActionText 让人头大!(===== 已解决 =====)

hiveer · 2022年02月16日 · 最后由 hiveer 回复于 2022年04月05日 · 1190 次阅读

第一次尝试 ActionText,遇到了好些让我头痛的问题。

重新部署会导致 attachments 失效

在本地环境,上传附件之后,如果不更新 (edit),即使是重启服务器,附件也是能正常找到并且渲染的。但是对于 staging 环境,通过 docker 打包,通过 docker-compose 部署,则不同了。上传附件之后,可以看到附件能正常的展示,但是如果重新部署,附件则会失效,实际上这个附件已经找不到了。暂时不晓得这个部署的操作,哪里会触发附件的失效。

direct uploads 的 URL 是 http 不是 https (===== 已解决 =====)

edit 会导致已经上传的 video(attachments)失效 (===== 已解决 =====)

补充项目的配置

目前我只在本地和 staging 做了测试,本地和 staging 的 ActiveStorage 都是基于 Aliyun OSS 而且使用的是同一个 bucket。

aliyun_staging:
  service: Aliyun
  access_key_id: <%= Rails.application.credentials.aliyun_oss[:access_key_id] %>
  access_key_secret: <%= Rails.application.credentials.aliyun_oss[:access_key_secret] %>
  bucket: "xxx-staging"
  endpoint: <%= Rails.application.credentials.aliyun_oss[:endpoint] %>
  path: "active_storage"
  public: true

Rails 的配置:

# config/environments/development.rb
# Store uploaded files on the local file system (see config/storage.yml for options).
config.active_storage.service = :aliyun_staging

# config/environments/staging.rb
# Store uploaded files on the local file system (see config/storage.yml for options).
config.active_storage.service = :aliyun_staging

对于上面提到的问题,我独立使用 ActiveStorage 的时候是没有的。如下面的代码所示,在同一个 model,我同时添加了富文本字段和一个 video 附件字段。 video 是能正确的上传和渲染的。但是通过 'rich_content' 上传的附件就存在上面所述的问题。

class Blog < ApplicationRecord
  has_rich_text :rich_content
  has_one_attached :video
end

这个跟 Action Text 没关系,取决于你的 storage, 你用的是 Disk, 在本地就是一直存在的,但是 Docker 容器重新部署时候 Disk 也是新的,以前存的就没了,和 Heroku 是一样的。你换成 AWS s3 这些服务就好了。https://edgeguides.rubyonrails.org/active_storage_overview.html

盲猜 storage 没有持久化

要用文件系统来存附件的话,docker 容器应该要配个数据卷吧。

应该要搞个“卷”,卷起来。

不是 ActionText 的问题,用 aliyun oss

建议深入学习 docker 以及 volume

FinnG 回复

我贴了下配置在文章中,本地和 test 环境都是用了 aliyun oss 的。

hooopo 回复

这个我不太确定了,需要探索下。不过如果没有持久化的话,那在新建之后在 show 页面渲染的时候应该就会出问题,只是我的猜测😁

@teddyinfi @lidashuang @flyweights @spike76 谢谢回复,我在文中贴了配置了。我使用了阿里云 OSS 的,而且独立使用 ActiveStorage 是没有问题的。所以应该不是各位说的 volume 或者 Disk 使用的问题。

上面只配置了 test 和 development,staging 用的是什么环境?

Rei 回复

是我表述不严谨,我说的 staging 其实就是 test 环境。只是我习惯把它叫做 staging 了。已经在文中修正了。

endpoint: <%= Rails.application.credentials.aliyun_oss[:endpoint] %>

截图上 endpoint 是 http,网页本身是 https,所以无法 loading

ericguo 回复

这里配置的是 Aliyun OSS 的 endpoint,上面提到的 https/http 的错误其实还没到使用这个配置。报错的域名地址还是本地:

假设我们 test 的地址是: https://blog-test.com

那么错误信息是这样的:

The page at 'https://blog-test.com/blogs/new' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://blog-test.com/rails/active_storage/direct_uploads'. This request has been blocked, the content must be served over HTTPS.
hiveer 回复

前面用了什么反向代理,是不是 protocol 没传递给 rails app。

目测最后查下来都和 ActionText 没关系

hiveer 回复

那你要么看看这个,我用过 ActionText,还定制过trix,印象中好像没遇到这个问题。。。

ericguo 回复

嗯嗯,谢谢啦,很好的建议。我下来再研究下。

coderliu 回复

是的,大概率是这样,不过集成环境的不同,可能会遇到不一样的问题,这也是分享的意义。

Rei 回复

👍,查验了,https 的问题,确实是这个原因。之前的配置是:

location / {
    proxy_pass "http://myapps";
    proxy_set_header X-Forwarded-Host blog-staging.com;
    proxy_redirect default;
}

改成了这个就好啦:

location / {
    proxy_pass "http://myapps";
    proxy_set_header X-Forwarded-Host blog-staging.com;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_redirect default;
}
hiveer 回复

真是不容易呀,我还以为是容器的问题,要是一开始知道 AS 没问题的话就不会怀疑 storage 了。破案了就好😁

FinnG 回复

嗯呢,这就是社区的力量啊,非常喜欢 Ruby 社区。

https/http 同源的问题解决了。还有两个问题我需要继续探索,到时候解决了,我会把方案都贴过来。

更新的时候附件会失效的问题已经找到原因,这个是 Rails 自身的一个 bug,当我们使用rich_text_area_tag的时候就会有这个问题,如果你使用的是rich_text_area就不会有这个问题。参考: https://github.com/rails/rails/issues/37405

需要 登录 后方可回复, 如果你还没有账号请 注册新账号