Search code examples
ruby-on-railsrubyspreeclass-eval

Override Controller in Spree - Circular dependency detected while autoloading constant


I'm trying to add action to Spree Admin PromotionsController like this

app/controllers/spree/admin/promotions_controller.rb

Spree::Admin::PromotionsController.class_eval do

  def users
    params[:q] ||= {}
    @search = @promotion.orders.reverse_chronological.ransack(params[:q])

    @users_hash = Hash.new(0)
    @search.result.each { |order| @users_hash[order.user] += 1 }

    @users_hash = Kaminari.paginate_array(@users_hash.to_a).page(params[:page])
  end
end

But I'm getting this error:

Circular dependency detected while autoloading constant Spree::Admin::PromotionsController

Also I'm tried to override controller totally:

 module Spree
   module Admin
     class PromotionsController < ResourceController
       before_action :load_data

       helper 'spree/admin/promotion_rules'
       def users
         params[:q] ||= {}
         @search = 
         @promotion.orders.reverse_chronological.ransack(params[:q])

         @users_hash = Hash.new(0)
         @search.result.each { |order| @users_hash[order.user] += 1 }

         @users_hash = 
         Kaminari.paginate_array(@users_hash.to_a).page(params[:page])
       end

       protected

       def location_after_save
         spree.edit_admin_promotion_url(@promotion)
       end

       def load_data
         @calculators = Rails.application.config.spree.calculators.promotion_actions_create_adjustments
         @promotion_categories = Spree::PromotionCategory.order(:name)
       end

       def collection
         return @collection if defined?(@collection)
         params[:q] ||= HashWithIndifferentAccess.new
         params[:q][:s] ||= 'id desc'

         @collection = super
         @search = @collection.ransack(params[:q])
         @collection = @search.result(distinct: true)
                         .includes(promotion_includes)
                         .page(params[:page])
                         .per(params[:per_page] || 
        Spree::Config[:admin_promotions_per_page])
      end

      def promotion_includes
        [:promotion_actions]
      end
   end
 end

That working perfectly, but it's looks like a crutches

Any help would be much appreciated, thanks

routes:

Spree::Core::Engine.routes.draw do
  Spree::Core::Engine.add_routes do
    namespace :admin do
      resources :promotions, only: [] do
        member do
          get 'users'
        end
      end
    end
  end
end

Solution

  • Issue is with the filename app/controllers/spree/admin/promotions_controller.rb

    In spree whenever we are doing class_eval on a controller/model we create the file with name 'original_filenanme_decorator.rb'

    i.e app/controllers/spree/admin/promotions_controller_decorator.rb

    Spree::Admin::PromotionsController.class_eval do
    
      def users
        params[:q] ||= {}
        @search = @promotion.orders.reverse_chronological.ransack(params[:q])
    
        @users_hash = Hash.new(0)
        @search.result.each { |order| @users_hash[order.user] += 1 }
    
        @users_hash = Kaminari.paginate_array(@users_hash.to_a).page(params[:page])
      end
    end
    

    Try changing the filename. It will surely solve your problem.

    Let me know if you still face any issue.