【问题标题】:Sorting Images or Attachments with Rails Active Storage and Stimulus使用 Rails Active Storage 和 Stimulus 对图像或附件进行排序
【发布时间】:2021-05-09 22:57:30
【问题描述】:

我试图在我的 rails 表单中创建一个可排序的画廊部分。我已经设置了基础知识,例如将位置列添加到 active_storage_attachments 数据库、活动存储本身、激励、激励排序或 sortable.js、视图以及所有要上传和排序的内容,但我无法弄清楚 javascript 端或控制器操作正确地做到这一点。我曾尝试将其他一些版本的黑客组合在一起,但无济于事。我已经尝试遵循 GoRails Sortable Stimulus 指南,但我无法弄清楚如何将其路由到附件,而不是我所在项目的实际模型,例如项目。我不需要对项目进行排序,而是对项目中的图像进行排序。我现在得到的错误是

NoMethodError (undefined method `each_with_index' for nil:NilClass):

我担心我没有获取其他人会得到的正确参数,因为我正在尝试连接到附件 ID,而不是我当前正在处理的项目 ID。

所以我正在使用 Rails 6、Ruby 3、Stimulus JS、Stimulus Sortable、Postgres、Active Storage 和 Webpacker。

对于我的控制器,我添加了这个来自 GoRails 论坛帖子的内容:

def sort_attachments
   
    params[:attachments].each_with_index do |id, index|
      ActiveStorage::Attachment.where(id: id).update_all(position: index + 1)
    end
  
    head :ok
  end

我在 before_action 中允许 :sort_attachments

resources :projects, only: [:sort_attachments] do
    member do
      patch 'projects/sort/:id', action: :sort_attachments, as: 'sort_attachments'
    end
end

和我的表单视图:

 <% if @project.persisted? %>
<% if @project.images.attached? %>
    <section class="pb-6  px-0">
        <div data-controller="sortable" data-sortable-animation-value="150" data-sortable-url="<%= sort_attachments_project_path %>" class="flex flex-wrap -mx-4 -mb-8">
          <% @project.images.order(:position).each do |images| %>
              <div data-id="<%= dom_id(attachment) %>" class="px-4 mb-8" >
                <%= image_tag images.variant(resize_to_limit: [150, 150]).processed, class: "rounded shadow-md"%>
              </div>
          <% end %>  
        </div>
     </section>
<% end %>
<% end %>

这是从那个论坛帖子和另一个使用 Jquery 的 Stackoverflow 上的帖子混合而成的。我宁愿坚持使用 Stimulus。

我的可排序控制器是:

import { Controller } from "stimulus"
import Sortable from "sortablejs"

export default class extends Controller {
  connect() {
    this.sortable = Sortable.create(this.element, {
      group: 'shared',
      animation: 150,
      onEnd: this.end.bind(this)
    })
  }

  end(event) {
    let id = event.item.dataset.id
    let data = new FormData()
    data.append("position", event.newIndex + 1)

    Rails.ajax({
      url: this.data.get("url").replace(":id", id),
      type: 'PATCH',
      data: data
    })
  }
}

任何帮助将不胜感激!提前谢谢你

【问题讨论】:

    标签: javascript ruby-on-rails sortablejs stimulusjs


    【解决方案1】:

    您没有发送附件,而只是发送参数 :positions,因此您会收到空异常错误。如果您想以这种特殊方式解决它,您需要通过 Ajax 调用发送附件参数。但是,从上面的代码中并不清楚 :attachments 参数应该包含什么。

    运行代码并将这一行添加到控制器方法的顶部以进行调试。现在,当您发送 ajax 请求时,它应该为您提供参数 raise params.inspect

    中包含的数据

    你已经解决了这个问题,让你自己很难。如果可能,您不应触摸附件数据库。我不知道为什么您希望每次用户登录时画廊都相同,但是您可以通过在索引方法中将图像设置为自己的变量来轻松解决这个问题,例如 @images 作为二维数组,然后将图像作为二维数组发送,并将响应作为与控制器排序方法中的 JS 相同的变量返回,如下所示:

    @images = param[:images].map do |attachment, position|
                [[attachment, position]]
               end
    

    如果您希望每次用户登录时排序都相同,那么一些缓存应该就足够了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-01
      • 2020-11-04
      • 2023-04-09
      • 1970-01-01
      • 2020-09-03
      • 2018-11-16
      • 2020-04-30
      相关资源
      最近更新 更多