Merge pull request #466 from indentlabs/aug-23-optimizations

Aug 23 optimizations (includes db migration)
This commit is contained in:
Andrew Brown 2019-09-07 23:01:59 -05:00 committed by GitHub
commit ea1720c9de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 115 additions and 30 deletions

View File

@ -358,21 +358,17 @@ class ContentController < ApplicationController
# Ugh not another one of these backfills
if content.position.nil?
content_to_order_first = if content.is_a?(AttributeCategory)
content_type_class = content.entity_type.titleize.constantize
content_type_class.attribute_categories(current_user, show_hidden: true)
if content.is_a?(AttributeCategory)
content.backfill_categories_ordering!
elsif content.is_a?(AttributeField)
content.attribute_category.attribute_fields
end
ActiveRecord::Base.transaction do
content_to_order_first.each.with_index do |content_to_order, index|
content_to_order.update_column(:position, 1 + index)
end
content.attribute_category.backfill_fields_ordering!
else
raise "Attempting to backfill ordering for a new class: #{content.class.name}"
end
end
if content.reload && content.insert_at(1 + sort_params[:intended_position].to_i)
content.reload
if content.insert_at(1 + sort_params[:intended_position].to_i)
render json: 200
else
render json: 500
@ -538,6 +534,7 @@ class ContentController < ApplicationController
@navbar_actions << {
label: 'Customize template',
class: 'right',
href: main_app.attribute_customization_path(content_type.name.downcase)
}
end

View File

@ -6,7 +6,7 @@ class DocumentMentionJob < ApplicationJob
def perform(*args)
document_id = args.shift
document = Document.find(document_id)
document = Document.find_by(id: document_id)
return unless document.present?
return if document.body.nil? || document.body.empty?

View File

@ -177,7 +177,7 @@ module HasAttributes
).pluck(:id)
# Todo these two queries should be able to be joined into one
name_field = AttributeField.find_by(
AttributeField.find_by(
user_id: user_id,
attribute_category_id: category_ids,
field_type: 'name'
@ -191,7 +191,7 @@ module HasAttributes
).pluck(:id)
# Todo these two queries should be able to be joined into one
name_field = AttributeField.find_by(
AttributeField.find_by(
user_id: user_id,
attribute_category_id: category_ids,
field_type: 'universe'
@ -205,7 +205,7 @@ module HasAttributes
).pluck(:id)
# Todo these two queries should be able to be joined into one
field = AttributeField.find_by(
AttributeField.find_by(
user_id: user_id,
attribute_category_id: category_ids,
label: label,

View File

@ -40,6 +40,50 @@ class AttributeCategory < ApplicationRecord
entity_type.titleize.constantize
end
def backfill_categories_ordering!
content_type_class = entity_type.titleize.constantize
category_owner = User.find(user_id)
categories = content_type_class.attribute_categories(category_owner, show_hidden: true).to_a
ActiveRecord::Base.transaction do
categories.each.with_index do |content_to_order, index|
content_to_order.update_column(:position, 1 + index)
# While we're doing this, we might as well backfill the fields also
content_to_order.backfill_fields_ordering!
end
end
end
def backfill_fields_ordering!
sorted_fields = attribute_fields.sort do |a, b|
a_value = case a.field_type
when 'name' then 0
when 'universe' then 1
else 2 # 'text_area', 'link'
end
b_value = case b.field_type
when 'name' then 0
when 'universe' then 1
else 2
end
if a.position && b.position
a.position <=> b.position
else
a_value <=> b_value
end
end
ActiveRecord::Base.transaction do
sorted_fields.each.with_index do |content_to_order, index|
content_to_order.update_column(:position, 1 + index)
end
end
end
private
def ensure_name

View File

@ -68,18 +68,6 @@ class ContentSerializer
value: value_for(field, content)
}
}.sort do |a, b|
a_value = case a[:type]
when 'name' then 0
when 'universe' then 1
else 2 # 'text_area', 'link'
end
b_value = case b[:type]
when 'name' then 0
when 'universe' then 1
else 2
end
# if a_value != b_value
# a_value <=> b_value
# else
@ -88,7 +76,20 @@ class ContentSerializer
if a[:position] && b[:position]
a[:position] <=> b[:position]
else
a_value = case a[:type]
when 'name' then 0
when 'universe' then 1
else 2 # 'text_area', 'link'
end
b_value = case b[:type]
when 'name' then 0
when 'universe' then 1
else 2
end
a_value <=> b_value
end
end

View File

@ -11,7 +11,9 @@
<div class="collapsible-header">
<span class="sortable-handle"><i class="material-icons grey-text">menu</i></span>
<i class="material-icons"><%= attribute_category.icon %></i>
<span class="js-category-label"><%= attribute_category.label %></span>
<div class="js-category-label">
<%= attribute_category.label %>
</div>
<% if hidden_category %>
<span class="grey-text">&mdash;hidden</span>
<% end %>

View File

@ -56,7 +56,7 @@
</li>
<% end %>
<% if content.documents.select { |doc| (current_user || User.new).can_read?(doc) }.any? %>
<% if editing && content.documents.select { |doc| (current_user || User.new).can_read?(doc) }.any? %>
<li class="collection-item tab">
<a href="#documents_panel" class="">
<i class="material-icons left"><%= Document.icon %></i>

View File

@ -0,0 +1,12 @@
class AddDocumentAnalysisIndices < ActiveRecord::Migration[5.2]
def change
add_index :documents, [:universe_id, :deleted_at]
add_index :attribute_categories, [:entity_type, :name, :user_id]
add_index :attribute_fields, [:attribute_category_id, :old_column_source, :user_id, :field_type], name: :attribute_fields_aci_ocs_ui_ft
add_index :attributes, [:user_id, :deleted_at]
add_index :attributes, [:attribute_field_id, :user_id, :entity_type, :entity_id, :deleted_at], name: :attributes_afi_ui_et_ei_da
end
end

View File

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2019_08_29_222650) do
ActiveRecord::Schema.define(version: 2019_09_08_015515) do
create_table "api_keys", force: :cascade do |t|
t.integer "user_id"
@ -2566,6 +2566,7 @@ ActiveRecord::Schema.define(version: 2019_08_29_222650) do
t.string "interests"
t.string "forums_badge_text"
t.boolean "keyboard_shortcuts_preference"
t.date "birthday"
t.index ["deleted_at", "username"], name: "index_users_on_deleted_at_and_username"
t.index ["deleted_at"], name: "index_users_on_deleted_at"
t.index ["email"], name: "index_users_on_email", unique: true

28
lib/tasks/backfill.rake Normal file
View File

@ -0,0 +1,28 @@
namespace :backfill do
desc "Start working through old categories/fields without position set"
task sortables_positions: :environment do
categories_to_position = AttributeCategory.where(position: nil).to_a
fields_to_position = AttributeField.where(position: nil).to_a
puts "Empty position backlog:\n\t- #{categories_to_position.count} categories\n\t- #{fields_to_position.count} fields"
while categories_to_position.any?
category = categories_to_position.pop
# Backfill all the positioning for this category's page's categories
category.backfill_categories_ordering!
# We can skip this if we're just backfilling with a single worker,
# but in case we're backfilling on multiple this fetches a recent
# copy of updates before proceeding. Technically still a possibility
# of Doing The Same Thing Twice, but a smaller possibility.
categories_to_position = AttributeCategory.where(position: nil).to_a
if rand(100) < 20
puts "Empty position backlog:\n\t-#{categories_to_position.count} categories\n\t-#{fields_to_position.count} fields"
end
end
puts "Done!"
end
end