From 5c48a2da5e1cc4c56e81ba42bd13507d87531e43 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 6 Nov 2019 19:35:48 -0300 Subject: [PATCH] =?UTF-8?q?ordenar=20m=C3=A1s=20exactamente?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/assets/javascripts/order.js | 2 -- app/controllers/posts_controller.rb | 9 --------- app/models/post.rb | 4 ++++ app/models/post_relation.rb | 5 +++-- app/services/post_service.rb | 19 +++++++------------ app/views/posts/index.haml | 3 ++- doc/reordenar.md | 10 ++++++++++ test/controllers/posts_controller_test.rb | 6 ++++-- 8 files changed, 30 insertions(+), 28 deletions(-) diff --git a/app/assets/javascripts/order.js b/app/assets/javascripts/order.js index 3c72a5f..9e93a30 100644 --- a/app/assets/javascripts/order.js +++ b/app/assets/javascripts/order.js @@ -8,9 +8,7 @@ $(document).on('turbolinks:load', function() { onlyBody: true, dragHandler: '.handle' }).on('drop', function(from, to, el, mode) { - // TODO: Detenerse al llegar al elemento que se movió $('.reorder').val(function(i,v) { return i; }); - $('.submit-reorder').removeClass('d-none'); }); }); diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 635cfe2..da0fe1f 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -11,15 +11,6 @@ class PostsController < ApplicationController @category = session[:category] = params.dig(:category) # TODO: Aplicar policy_scope @posts = @site.posts(lang: I18n.locale) - - if params[:sort_by].present? - begin - @posts.sort_by! do |p| - p.send(params[:sort_by].to_s) - end - rescue ArgumentError - end - end end def show diff --git a/app/models/post.rb b/app/models/post.rb index e89e712..14f7ce4 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -60,6 +60,10 @@ class Post < OpenStruct path.basename end + def sha1 + Digest::SHA1.hexdigest id + end + # Levanta un error si al construir el artículo no pasamos un atributo. def default_attributes_missing(**args) DEFAULT_ATTRIBUTES.each do |attr| diff --git a/app/models/post_relation.rb b/app/models/post_relation.rb index 40ccaa9..ce1063b 100644 --- a/app/models/post_relation.rb +++ b/app/models/post_relation.rb @@ -33,9 +33,10 @@ class PostRelation < Array alias find_generic find - def find(id) + # Encontra un post por su id convertido a SHA1 + def find(id, sha1: false) find_generic do |p| - p.id == id + p.sha1 == (sha1 ? id : Digest::SHA1.hexdigest(id)) end end diff --git a/app/services/post_service.rb b/app/services/post_service.rb index 890a77f..768c1fd 100644 --- a/app/services/post_service.rb +++ b/app/services/post_service.rb @@ -39,26 +39,21 @@ PostService = Struct.new(:site, :usuarie, :post, :params, keyword_init: true) do post end - # Reordena todos los posts que soporten orden de acuerdo a un array - # con las nuevas posiciones. La posición actual la da la posición en + # Reordena todos los posts que soporten orden de acuerdo a un hash de + # ids y nuevas posiciones. La posición actual la da la posición en # el array. # - # [ 1, 0, 2 ] => mover el elemento 2 a la posición 1, mantener 3 + # { sha1 => 2, sha1 => 1, sha1 => 0 } def reorder posts = site.posts(lang: lang) - reorder = params.require(:post).permit(reorder: []) - .try(:[], :reorder) - .try(:map, &:to_i) || [] + reorder = params.require(:post).permit(reorder: {}).try(:[], :reorder) - # Tenemos que pasar un array con la misma cantidad de elementos - return false if reorder.size != posts.size - - files = reorder.map.with_index do |new, cur| - post = posts[cur] + files = reorder.keys.map do |id| + post = posts.find(id, sha1: true) next unless post.attributes.include? :order post.usuaries << usuarie - post.order.value = new + post.order.value = reorder[id].to_i post.path.absolute end.compact diff --git a/app/views/posts/index.haml b/app/views/posts/index.haml index 3896354..2418b69 100644 --- a/app/views/posts/index.haml +++ b/app/views/posts/index.haml @@ -42,7 +42,8 @@ %td .handle = image_tag 'arrows-alt-v.svg' - = hidden_field 'post[reorder]', '', value: i, class: 'reorder' + = hidden_field 'post[reorder]', post.sha1, + value: i, class: 'reorder' %td = link_to post.title.value, site_post_path(@site, post.id) diff --git a/doc/reordenar.md b/doc/reordenar.md index bf5c0c4..99a9ed0 100644 --- a/doc/reordenar.md +++ b/doc/reordenar.md @@ -13,3 +13,13 @@ Como el orden es un metadato, tenemos que ignorar los tipos de posts que no lo tienen El orden por defecto es orden natural, más bajo es más alto. + +El problema que tiene esta implementación es que al reordenar los posts +necesitamos mantener el orden original sobre el que estabamos ordenando, +sino terminamos aplicando un orden incorrecto. Esto requiere que +implementemos una forma de mantener el orden entre sesiones e incluso +general. Nos vendría bien para no tener que recargar el sitio una y +otra vez. + +Lo más controlado sería enviar exactamente el id del post con su nueva +ubicación en el orden. Esta es la implementación anterior. diff --git a/test/controllers/posts_controller_test.rb b/test/controllers/posts_controller_test.rb index 684818b..3075948 100644 --- a/test/controllers/posts_controller_test.rb +++ b/test/controllers/posts_controller_test.rb @@ -145,7 +145,7 @@ class PostsControllerTest < ActionDispatch::IntegrationTest test 'se pueden reordenar' do lang = I18n.available_locales.sample posts = @site.posts(lang: lang) - reorder = posts.each_index.to_a.shuffle + reorder = Hash[posts.map(&:sha1).shuffle.each_with_index.to_a] post site_posts_reorder_url(@site), headers: @authorization, @@ -156,6 +156,8 @@ class PostsControllerTest < ActionDispatch::IntegrationTest assert_equal I18n.t('post_service.reorder'), @site.repository.rugged.head.target.message assert_equal reorder, - @site.posts(lang: lang).map(&:order).map(&:value) + Hash[@site.posts(lang: lang).map do |p| + [p.sha1, p.order.value] + end] end end