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

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

第一次尝试 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 #0 回复

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

hooopo #1 回复

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

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

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

Rei #9 回复

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

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

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

ericguo #11 回复

这里配置的是 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 #12 回复

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

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

hiveer #12 回复

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

ericguo #15 回复

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

coderliu #14 回复

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

Rei #9 回复

👍,查验了,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 #6 回复

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

FinnG #19 回复

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

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

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

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