Сортировка изображений с использованием Active Storage - PullRequest
0 голосов
/ 03 декабря 2018

Я экспериментирую с Active Storage для управления изображениями.У меня работает несколько загрузок, но я хочу использовать позицию activ_as_list с сортировкой jQuery для управления их заказом с помощью ajax, как в видео на этом сайте .В обычной модели я бы запустил миграцию, чтобы добавить положение в модель.Но, похоже, у меня нет доступа к моделям Blob или Attachment.Как бы я занялся этим?Или я должен вернуться к использованию Carrierwave?Буду признателен за любую помощь.

Для уточнения, позвольте мне добавить код.

show.html.erb

<p id="notice"><%= notice %></p>

<p>
  <strong>Title:</strong>
  <%= @post.title %>
</p>

<p>
  <strong>Content:</strong>
  <%= @post.content %>
</p>

<% if @post.images.attached? %>
<p>
  <strong>Images:</strong>
  <br>
  <div id="images" class="list-group" data-url="<%= sort_posts_path %>">
  <% @post.images.order(:position).each do |image| %>
    <%= link_to image_tag image.variant(resize: "200x200"), class: "list-group-item", id: dom_id(image) %>
  <% end %>
  </div>
</p>
<% end %>

<%= link_to 'Edit', edit_post_path(@post) %> |
<%= link_to 'Back', posts_path %>

posts.js

document.addEventListener("turbolinks:load", function() {

  $("#images").sortable({
    update: function(e, ui) {
      /* Update active storage database entry for each POST image. */
      /* This is the RAILS AJAX from the tutorial */
      Rails.ajax({
        url: $(this).data("url"),
        type: "PATCH",
        data: $(this).sortable('serialize'),
    }
  });

});

rout.rb

Rails.application.routes.draw do
  resources :posts do
    collection do
      patch :sort
    end
  end
end

posts_controller.rb

def sort
  params[:image].each_with_index do |id, index|
    Post.image.where(id: id).update_all(position: index + 1)
  end

  head :ok
end

Ответы [ 2 ]

0 голосов
/ 19 января 2019

Это то, что я в итоге сделал, чтобы заставить все это работать в реальном приложении.Удивительно все, что вошло в эту «простую» функциональность.

Gemfile

gem 'jquery-rails'
gem 'jquery-ui-rails'
gem 'acts_as_list'

Миграция для добавления position в Active Storage.

class AddPositionToActiveStorageAttachments < ActiveRecord::Migration[5.2]
  def change
    add_column :active_storage_attachments, :position, :integer, default: 0
  end
end

sorting.js

Это позволяет нам сортировать что угодно, используя класс sort-me.

$(function() {

  $(".sort-me").sortable({
    update: function(e, ui){
      ui.placeholder.height(ui.item.height());
      Rails.ajax({
        url: $(this).data("url"),
        type: "PATCH",
        data: $(this).sortable('serialize')
      });
    }
  }).disableSelection();

});

edit.html.erb

Это фрагмент соответствующего кода на странице.Добавление класса sort-me к содержащему элементу div сделает элементы сортировки из следующего набора элементов.

<div id="product-attachments" class="sort-me" data-url="<%= sort_attachments_admin_products_path %>">
  <% @product.images.order(:position).each do |attachment| %>
    <div id="<%= dom_id(attachment) %>" class="ui-state-default image-box">
      <%= image_tag attachment.variant(combine_options: {auto_orient: true, thumbnail: '200x200^', gravity: 'center', extent: '200x200' }) %>
      <%= link_to "Delete", delete_image_admin_products_path(@product.id, attachment.id), method: :delete, class: "btn btn-xs", data: {confirm: "Are you sure?"} %>
    </div>
  <% end %>
</div>

rout.rb

Это соответствующиемаршруты.В этом случае использовалось пространство имен администратора.Поэтому, если вы используете это без него, убедитесь, что ваши маршруты / пути не включают в себя административную часть.

namespace 'admin' do
  resources :products do
    collection do
      patch '/products/sort/:id', action: :sort_attachments, as: 'sort_attachments'
      delete '/products/:id/images/:image_id', action: 'delete_image', as: 'delete_image'
    end
  end
end

products_controller.rb

Соответствующие действия контроллера для сортировка и удаление маршрутов.

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

  head :ok
end

def delete_image
  ActiveStorage::Attachment.where(id: params[:image_id])[0].purge
  redirect_to edit_admin_product_path(params[:id]), notice: 'Image was successfully deleted.'
end
0 голосов
/ 03 декабря 2018

ОБНОВЛЕНИЕ Гораздо лучший способ Учитывая, что MyModel.images возвращает массив моделей ActiveStorageAttachment, я только что провел тест, создав миграцию для добавления столбца позиции в таблицу active_storage_attachments. Затем с помощью этого поляпорядок изображений работает идеально

rails g migration add_order_by_to_active_storage_attachments position:integer

Очевидно, что не забудьте запустить миграцию, и вы можете отредактировать миграцию, чтобы обновить поле позиции для существующих записей, прежде чем запускать его.

Теперь вы можете установить в поле позиции любые значения, которые вы хотите, а затем вы можете просто использовать my_model.images.order(:position)

Если вам было бы полезно расширить этот ответ, просто спросите в комментариях

ОБНОВЛЕНИЕ для большей ясности, это массив изображений, которые нужно отсортировать, верно?Чтобы это произошло, поле позиции, которое вы только что создали в миграции, должно быть установлено, когда форма отправляется обратно в контроллер после того, как изображения были реорганизованы в представлении.

Итак,в соответствующих действиях контроллера, обновите и создайте, вы можете выполнить цикл @post.images, устанавливающий положение для каждого изображения, и сохранить изображение обратно в базу данных.Это гарантирует, что при просмотре изображений с помощью @post.images.order(:position) они будут отображаться в правильном порядке.

...