All threads / Model not updated correctly on drag (Apartment + Vue + Rails 6)

Ask A Question

Notifications

You’re not receiving notifications from this thread.

Model not updated correctly on drag (Apartment + Vue + Rails 6)

Alan Dew asked in Rails

Stack used: Rails 6

Gems used: Apartment, Devise, Vue, vuedraggable, acts_as_list

Hi guys! I'm trying to create a "Trello" type app (following the Vue.js Trello Clone in Rails screencast). Right now, I'm trying to implement vuedraggable, but since i'm still learning Rails and first time using Apartment it's driving me crazy!

So here is my problem: I have 3 List columns right now. I want to be able to drag each List column around, and update their position, so that when I refresh my page they keep the updated position. Right now, when I drag my columns it works great live, but the position modification isn't saved correctly. When I refresh my page, the columns take their inital position, so their position aren't saved correctly. I guess since I'm using Apartment, I'm not using the right method to save it.

Here is my Lists Controller :

class ListsController < ApplicationController
  before_action :set_list, only: %i[show edit update destroy move]

  def move
    @list.insert_at(list_params[:position].to_i)
    render action: :show
  end

  private

  def set_list
    @list = List.find(params[:id])
  end

  def list_params
    params.require(:list).permit(:name, :position)
  end
end

And here is my Vue component :

<template>
  <draggable v-model="lists" group=".lists" class="row dragArea" @end="listMoved">
    <div v-for="(list, index) in lists" class="col-3 mr-5">
      <h5>{{ list.name }}</h5>
      <hr />

      <div v-for="(card, index) in list.cards" class="card card-body mb-3">
        {{ card.name }}
      </div>

      <div class="card card-body">
        <textarea v-model="messages[list.id]" class="form-control"></textarea>
        <button v-on:click="submitMessages(list.id)" class="btn btn-secondary">Ajouter</button>
      </div>
    </div>
  </draggable>
</template>

<script>
import Rails from '@rails/ujs';
import draggable from 'vuedraggable';

export default {
  components: {draggable},

  props: ['original_lists'],

  data: function() {
    return {
      messages: {},
      lists: this.original_lists
    };
  },

  methods: {
    listMoved: function(event) {
      var data = new FormData
      data.append("list[position]", event.newIndex + 1)
      Rails.ajax({
        beforeSend: () => true,
        url: `/lists/${this.lists[event.newIndex].id}/move`,
        type: "PATCH",
        data: data,
        dataType: "json",
      })
    },
  }
};
</script>

<style scoped>
.dragArea{
  min-height: 10px;
}
</style>

And here is what's logged in my terminal when moving (dragging) the first List column in third position:

Started PATCH "/lists/1/move" for 127.0.0.1 at 2019-12-09 18:54:17 +0100
   (0.0ms)  SELECT sqlite_version(*)
  ↳ config/initializers/apartment/apartment.rb:52:in `block (2 levels) in <main>'
   (0.1ms)  SELECT "users"."subdomain" FROM "users"
  ↳ config/initializers/apartment/apartment.rb:52:in `block (2 levels) in <main>'
   (0.0ms)  SELECT sqlite_version(*)
Processing by ListsController#move as JSON
  Parameters: {"list"=>{"position"=>"3"}, "id"=>"1"}
  List Load (0.1ms)  SELECT "lists".* FROM "lists" WHERE "lists"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
  ↳ app/controllers/lists_controller.rb:76:in `set_list'
   (0.0ms)  begin transaction
  ↳ app/controllers/lists_controller.rb:68:in `move'
  List Load (0.1ms)  SELECT "lists".* FROM "lists" WHERE "lists"."id" = ? LIMIT ?   [["id", 1], ["LIMIT", 1]]
  ↳ app/controllers/lists_controller.rb:68:in `move'
  List Load (0.1ms)  SELECT "lists".* FROM "lists" WHERE (1 = 1) AND ("lists"."position" IS NOT NULL) ORDER BY "lists"."position" DESC LIMIT ?  [["LIMIT", 1]]
  ↳ app/controllers/lists_controller.rb:68:in `move'
  List Update All (0.0ms)  UPDATE "lists" SET "position" = ("lists"."position" - 1), "updated_at" = '2019-12-09 17:54:17.046407' WHERE (1 = 1) AND ("lists".id != 1) AND ("lists"."position" > 1) AND ("lists"."position" <= 3)
  ↳ app/controllers/lists_controller.rb:68:in `move'
   (0.0ms)  commit transaction
  ↳ app/controllers/lists_controller.rb:68:in `move'
  Rendering lists/show.html.erb within layouts/application
  Rendered lists/show.html.erb within layouts/application (Duration: 0.2ms | Allocations: 85)
[Webpacker] Everything's up-to-date. Nothing to do
  User Load (0.1ms)  SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ?  [["id", 3], ["LIMIT", 1]]
  ↳ app/views/shared/_header.html.erb:13
  Rendered shared/_header.html.erb (Duration: 1.9ms | Allocations: 1584)
Completed 200 OK in 13ms (Views: 6.9ms | ActiveRecord: 0.6ms | Allocations: 10514)
   (0.1ms)  SELECT "users"."subdomain" FROM "users"
  ↳ config/initializers/apartment/apartment.rb:52:in `block (2 levels) in <main>'
   (0.0ms)  SELECT sqlite_version(*)
Join the discussion

Want to stay up-to-date with Ruby on Rails?

Join 38,558+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.

    logo Created with Sketch.

    Ruby on Rails tutorials, guides, and screencasts for web developers learning Ruby, Rails, Javascript, Turbolinks, Stimulus.js, Vue.js, and more. Icons by Icons8

    © 2020 GoRails, LLC. All rights reserved.