Rails: saving an ordered list with empty values

Hypothetical: I want 32 sections with 4 slots. Each slot can hold a person from a drag list.

What is the best way to maintain your position (and return back to the user) by keeping spaces or “slots” in the right place?

Now I have something like a script, but when I save it, I just send it data-idas an array, so it keeps their order, but does not take into account empty spaces ... and, of course, my method of reading the list returns the array back. i.e. If I have, when creating: Tim, empty, Bob, my controller saves empty ['Tim', 'Bob'], and when the user reboots, they see: Tim, Bob, empty, empty

So, this is a question of two parties:

1) How to save a list of users , including spaces And what is the best way to do this with rails / mongoid? Again, I currently know how to save, I just don't know if it is better to use an array / object or what ...

2) How to rebuild / read / load the list?

Fiddle : Imagine this is another 31 sections to fill ... this is just one section.

EDIT

If I used a gem, for example acts_as_list, would it be bad (since each user will have 128 entries) to have a row per user element? In my opinion, this will make the mango collection have too many documents, but I also have a poor understanding of mongodb.

user_id, 
pick_id,
position

instead

user_id,
picks [
    "pick_id_1234",
    "pick_id_1235",
    "pick_id_1236"
    ]
+4
4

Mongoid, ;


, -

, , ( ). , (I.E ..), sessions

, . ActiveRecord , mongoid ():

#app/models/list.rb
Class List < ActiveRecord::Base
   belongs_to :section
   belongs_to :user
end

#app/models/user.rb
Class User < ActiveRecord::Base
    has_many :lists
end

#app/models/section.rb
Class UserListPosition < ActiveRecord::Base
    has_many :lists
    has_many :users, through: :lists
end

Schemas

users
id | name | email | created_at | updated_at

sections
id | details | about | section | created_at | updated_at

lists
id | section_id | user_id | created_at | updated_at

#app/controllers/lists_controller.rb
def new
    @list = 32.times do { List.new } ##needs refactoring
end

def create
    @list = List.new(list_params)
    @list.save
end

private

def list_params
    params.require(:list).permit(:section_id, :user_id)
end

#app/views/lists/new.html.erb
<%= form_for @list do |f| %>
    <% Section.all.each do |section| %>
        ##inputs here
    <% end %>
    <%= f.submit %>
<% end %>
+2

, , Person.

, Struct, , .

# /struct/slotter.rb
Slotter = Struct.new(:section_id, :slot1, :slot2, :slot3, :slot4)

# assuming slots are always the Person#id, i.e. Integer representation 
# of person by their id. Also would work with UUIDs or BSON, etc. 
# The section number would be stored in the variable *section_no*
Slotter.new(section_no, id_1, id_2, id_3, id_4)

# You can also pass a block to a Struct  so you could write read
# accessors for the data, again this assumes Person class exists
Slotter = Struct.new(:section_id, :slot1, :slot2, :slot3, :slot4) do 

  def read_slot1
    Person.find(slot1)
  end

end

, Marshal.dump , .

Javascript, JSON, to_json, Rails. to_json, ..

. , , Person Integer. .:)

, , , , JavaScript, , Angular.js, Rails . JSON , .

Update

. Ruby Old Ruby / . Railscast.

. n . , SLOTS . , . slot5 4, .

# 2

  • / (, , )
  • , , . .. , .

, , . , , x, , :

def in_slot?(slot)
  slots.include?(slot.to_s)
end

, SQL. .. ( ). :

all.keep_if {|p| p.is_slot?(:slot1)}

, , . 1 slot3, , 5, slots_mask 5.

, , , SQL. ​​ , , , .

+2

, : 1. 2. , ( ), .

, , .

!

Front End

, , - JSON , ( , ). , : http://jsfiddle.net/3SSqM/41/ ( , windows.document, - , , ). :

  • 'picks-group-NUMBER'
  • JS indexes, , 0-127, 1- 0 32- 127
  • , (.. NUMBER ), JS . , , , :

     $('.picks-group').sortable({
      tolerance: "pointer",
      start: // some code
      stop: function (event, ui) {
          sorting = false;
          sectionNumber = getSectionNumber($(this)[0].id);
          $(this).find('li').each(function (i, obj) {
              var index = sectionNumber + i;
              indexes[String(index)] = $(obj).attr('data-id');
          });
      },
      change: // some code
    });
    

, "", . , indexes JSON Rails, . JSON- JSON .

Back End

Mongoid - . , . , , -, , , . - :

Class Pick
  include Mongoid::Document

  field :picks, type: Hash

end

! ?

, , , , . , , :

  • ? .
  • , . , .

, , , - :

Class Pick
  include Mongoid::Document

  field :pick_0
  field :pick_1
  # ... you get the idea
  field :pick_127

end

, pick_0 pick_127, , , , , , : http://mongoid.org/en/mongoid/docs/documents.html#dynamic_fields

, : . , , , , , -, , . .

+1

. Mongodb, .

Either an c array nullto represent spaces, so Tim, empty, Bob, empty becomes ['Tim', null, 'Bob', null]in JS / Mongodb or stores location identifiers with user IDs, so you have one [[0, 'Tim'], [2, 'Bob']]. Which one is more efficient depends on how many slots are left empty on average. Using nullis likely to be easier, so I would approve of it, all other things being equal.

-1
source

Source: https://habr.com/ru/post/1528019/


All Articles