1
\$\begingroup\$

My friend asked me to write a tool that lets users bulk add/edit labels (taxons) to store (spree commerce) products.

I came up with this, curious to know if you guys find the code readable/maintainable.

# engines/admin_ui/app/controllers/admin_ui/product_taxons_controller.rb
module AdminUi
  class ProductTaxonsController < AdminUi::ApplicationController
    before_filter :load_products_and_taxons

    def index
    end

    def apply
      @toolbar_state.each do |directive|
        if ( (directive["original_state"] == "fa-square-o" && directive["current_state"] == "fa-check-square") ||
             (directive["original_state"] == "fa-minus-square" && directive["current_state"] == "fa-check-square") )
          @checked_products.each do |product_id|
            unless Spree::Product.find(product_id).taxons.where(id: directive["taxon_id"].to_i).present?
              Spree::Product.find(product_id).taxons << Spree::Taxon.find(directive["taxon_id"])
            end
          end
        elsif ( (directive["original_state"] == "fa-check-square" && directive["current_state"] == "fa-square-o") ||
                (directive["original_state"] == "fa-minus-square" && directive["current_state"] == "fa-square-o") )
          @checked_products.each do |product_id|
            Spree::Product.find(product_id).taxons.delete( Spree::Taxon.find(directive["taxon_id"]) )
          end
        end
      end
    end

    def dropdown
    end

    private

    def load_products_and_taxons
      @products = Spree::Product.unscoped.where('deleted_at IS NULL').order("created_at DESC")
      @table_state = params["table_state"] ? (params["table_state"].map { |k,v| v}) : []
      @toolbar_state = params["toolbar_state"] ? (params["toolbar_state"].map { |k,v| v}) : []
      @checked_products = @table_state.select { |x| x["is_checked"]=="1" }.map do |ts|
        ts["product_id"].to_i
      end
      num_checked_products = @checked_products.size

      @all_taxons = Spree::Taxon.order(:name).map do |taxon|
        num_products_having_taxon = 0

        if num_checked_products > 0
          num_products_having_taxon = ActiveRecord::Base.connection.execute(
            "select count(*) from spree_products_taxons " \
            "where taxon_id=#{taxon.id} AND " \
            "product_id IN (#{@checked_products.join(',')})"
          ).to_a[0]["count"].to_i
        end
        state = "fa-square-o"
        state = "fa-minus-square" if num_products_having_taxon > 0
        state = "fa-check-square" if num_products_having_taxon == num_checked_products && num_checked_products!=0
        { taxon_id: taxon.id, name: taxon.name, state: state, toggleable_states: toggleable_states(state) }
      end
    end

    def toggleable_states(state)
      if state == "fa-square-o"
        "fa-check-square,fa-square-o"
      elsif state == "fa-minus-square"
        "fa-check-square,fa-square-o,fa-minus-square"
      elsif state == "fa-check-square"
        "fa-square-o,fa-check-square"
      end
    end

  end
end

In engines/admin_ui/app/views/admin_ui/product_taxons/_scripts.html.erb

<script>

// toggles icon like gmails labeling tool does
function toggle_f8fcac5(wrapping_element) {
    var element = $(wrapping_element).find("i").first();
    var toggleable_states = $(wrapping_element).data('toggleable-states').split(',');
    var current_state_index = toggleable_states.indexOf( $(wrapping_element).data("current-state") );
    var next_state_index = current_state_index+1;
    if (next_state_index == toggleable_states.length) {
        next_state_index = 0;
    }
    $(wrapping_element).data("current-state",toggleable_states[next_state_index]);
    $(element).removeClass('fa-square-o fa-minus-square fa-check-square').addClass(toggleable_states[next_state_index]);
}

// when the user hasn't requested any chance, the apply button is not shown
function hide_apply_button_dbef189() {
    num_dropdown_items = $(".dropdown-items-c7f057a").length;
    var untouched_dropdown_items = $(".dropdown-items-c7f057a").filter( function(index) {
        return ( $(this).data("original-state") == $(this).data("current-state") )
    }).length;
    if ( num_dropdown_items == untouched_dropdown_items ) {
        $(".wrapper-e9e4f8f").addClass('invisible');
    }
    else {
        $(".wrapper-e9e4f8f").removeClass('invisible');
    }

}

// prevent table-checkboxes meddling when dropdown is open
$("body").on("click", ".rows-b80f8d6 input[type='checkbox']", function(event) {
    if ( $('.wrapper-fd9d361').hasClass('open') ) {                                                                                         return false;
    }
});

// toggles icon
$("body").on("click", ".dropdown-items-c7f057a", function() {
    //event.preventDefault();
    event.stopPropagation();
    toggle_f8fcac5(this);
    hide_apply_button_dbef189();
})

// appends view state to the ujs/ajax http request
$("body").on("ajax:before", ".apply-button-c515cd5, .dropdown-button-ae27033", function() {
    var a = $.param(
                     {
                         "table_state": table_state_b5512e0(),
                         "toolbar_state": toolbar_state_c6eeceb()
                     });
    $(this).data('params', a);

});


// updates data attribute when check boxes are checked
$("body").on("change", ".rows-b80f8d6 input[type='checkbox']", function(event) {
    if($(this).is(':checked')) {
        $(this).closest("tr").data('is-checked', '1');
    } else {
        $(this).closest("tr").data('is-checked', '0');
    }
});

// returns the state of the _toolbar partial
// as a json structure
function toolbar_state_c6eeceb() {
    return $(".dropdown-items-c7f057a").map(
        function(index,elem) {
            return {
                "original_state": $(elem).data("original-state"),
                "current_state": $(elem).data("current-state"),
                "taxon_id": $(elem).data("taxon-id"),
            }
        }
    ).get()
}

// returns the state of the _table partial
// as a json structure
function table_state_b5512e0() {
    return $("tr.rows-b80f8d6").map(
                             function(index, elem) {
                                return {
                                    "is_checked": $(elem).data("is-checked"),
                                    "product_id": $(elem).data("product-id")
                                }
                              }
    ).get()
}
</script>

In engines/admin_ui/app/views/admin_ui/product_taxons/apply.js.erb

if ( $('.wrapper-fd9d361').hasClass('open') ) {
    $(".wrapper-dc38f9f").html("<%= j render(partial: 'table') %>");
    $('.wrapper-fd9d361').removeClass('open');
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.