如何通过 Hotwire Turbo 流正确渲染图像?

问题描述 投票:0回答:3

我的问题:使用 Hotwire/Turbo 渲染图像时,所有 URL 均使用主机

example.org
渲染,而不是我的实际主机名。常规视图很好,但通过 Turbo 流渲染部分视图会导致 ActiveStorage URL,如
http://example.org/.../

上下文:我有一个简单的 Todo 应用程序,带有工作视图、部分视图和涡轮流,它们一起显示 Todo 和关联用户的列表。当我将用户加入 Todo 时,turbo 流会渲染正确的部分,并将用户的姓名和头像放入我想要的 DOM 中。但是,来自 ActiveStorage 的图像 URL 包含

example.org
主机名。

我在

config/environments/*.rb
中设置了我的标准 URL 选项,包括
routes.default_url_options[:host]
config.action_mailer.default_url_options[:host]
。我还了解了文件
config/initializers/application_controller_renderer.rb
,您可以在其中设置
http_host
参数;但是,我已经设置了
http_host
,即
https
布尔值,Turbo 仍然使用 example.org 渲染我的
image_tag

此外,我发现有关如何以编程方式操作默认渲染器(为了解决问题)的建议有限。 此来源说要抓取

ApplicationController.renderer
并覆盖属性,如下所示:

renderer = ApplicationController.renderer.new(
  http_host: request.host_with_port,
  https: (request.protocol == "https://"),
  "rack.session": request.session
)

但是

broadcast_action_to
方法似乎不接受
renderer
参数,所以这实际上对 Turbo 中的我没有帮助。

肯定有一个配置我丢失了,但我在 Turbo 或 Hotwire 文档中没有找到它。

ruby-on-rails hotwire-rails turbo
3个回答
7
投票

我失踪了

config.action_controller.default_url_options
。一旦我将其配置为与其他 default_url_options 相同,我的链接就开始正确呈现。


0
投票

就我而言,我有一个动态

default_url_options
,因为我的应用程序是多租户的,所以我将其添加到
ApplicationController

def default_url_options
  { host: SiteSetting[:entity].domains.first.name, protocol: 'https' }
end

我认为这一切都源于

asset_host
配置,因此通常图像 URL 中包含资产主机。
ActiveStorage
url 使用当前的默认主机(当然不是资产主机),因为它们实际上是重定向路由而不是实际文件。我假设如果未设置
asset_host
,那么图像路径将是相对的而不是绝对的?如果无论如何都能让他们保持相对关系那就太理想了。


0
投票

我们可以直接使用

<%= image_tag url_for(user.avatar) %>

显示 Turbo Stream 中的任何图像。

例如,使用 Turbo Stream 显示实时发布通知,我们可以使用以下代码来发布部分

<!-- app/views/notifications/_post.html.erb -->
<div class="flex items-start space-x-4 bg-white p-4 rounded-lg shadow-md">
  <% if notification.item.user.avatar.attached? %>
    <%= image_tag url_for(notification.item.user.avatar), class: 'w-10 h-10 rounded-full' %>
  <% end %>
  <div class="flex-grow">
    <p class="text-gray-700">
      <span class="font-semibold text-gray-900"><%= notification.item.user.username %></span>
      added a new post:
    </p>
    <p class="mt-1 text-gray-600">
      <%= link_to notification.item.content.truncate(100), notification.item, class: "underline text-blue-600 hover:text-blue-800 font-medium" %>
    </p>
    <p class="text-sm text-gray-400 mt-1">
      <%= time_ago_in_words(notification.item.created_at) %> ago
    </p>
  </div>
  <% if notification.item.image.attached? %>
    <div class="flex-shrink-0">
      <%= image_tag url_for(notification.item.image), class: 'w-20 h-20 object-cover rounded-lg' %>
    </div>
  <% end %>
</div>
© www.soinside.com 2019 - 2024. All rights reserved.