0

我面临以下问题:

ActionController::RoutingError (未初始化常量 Spree::Api::AramexAddressController::AramexAddressValidator):
app/controllers/spree/api/aramex_address_controller.rb:2:in <class:AramexAddressController>
app/controllers/spree/api/aramex_address_controller.rb:1:in<top (required)>

我在我的controllers/spree/api/aramex_address_controller.rb中包含了以下内容:

class Spree::Api::AramexAddressController < ApplicationController
  include AramexAddressValidator

  # fetch cities from aramex api
  def fetch_cities_from_aramex_address
    response = []
    zones = Spree::ShippingMethod.where(['LOWER(admin_name) like ?', '%aramex%']).map(&:zones).flatten
    if zones.map(&:countries).flatten.map(&:iso).include?(params['country_code'])
      response = JSON.parse(fetch_cities(params['country_code']))['Cities']
    end
    respond_to do |format|
      format.json { render :json => response, :status => 200 }
    end
  end

  # Validate address for aramex shipping
  def validate_address_with_aramex
    begin
      zones = Spree::ShippingMethod.where(['LOWER(admin_name) like ?', '%aramex%']).map(&:zones).flatten
      final_response = {}
      if zones.map(&:countries).flatten.map(&:iso).include?(params[:b_country])
        final_response[:b_errors] = confirm_address_validity(params[:b_city], params[:b_zipcode], params[:b_country])
      end
      if zones.map(&:countries).flatten.map(&:iso).include?(params[:s_country]) && params[:use_bill_address] == "false"
        final_response[:s_errors] = confirm_address_validity(params[:s_city], params[:s_zipcode], params[:s_country])
      end
    rescue
      return true
    end
    respond_to do |format|
      format.json { render :json => final_response, :status => 200 }
    end
  end

  # Confirm address validity with Aramex address validatio API
  def confirm_address_validity(city, zipcode, country)
    response = JSON.parse(validate_address(city, zipcode, country))
    if response['HasErrors'] == true
      if response['SuggestedAddresses'].present?
        response['Notifications'].map{|data| data['Message']}.join(', ') + ', Suggested city name is - ' + response['SuggestedAddresses'].map{|data| data['City']}.join(', ')
      else
        if response['Notifications'].first['Code'] == 'ERR06'
          response['Notifications'].map{|data| data['Message']}.join(', ')
        else
          cities_response = JSON.parse(fetch_cities(country, city[0..2]))
          cities_response['Notifications'].map{|data| data['Message']}.join(', ') + ', Suggested city name is - ' + cities_response['Cities'].join(' ,')
        end
      end
    end
  end
end

在我的路线文件中,我提到了:

get 'validate_address_with_aramex', to: 'aramex_address#validate_address_with_aramex'
get 'fetch_cities_from_aramex_address', to: 'aramex_address#fetch_cities_from_aramex_address'

我在assets/javascripts/spree/frontend/checkout/address.js中包含了以下 JS 调用,用于提交的 Aramex Ajax 验证:

Spree.ready(function($) {
    Spree.onAddress = function() {
        var call_aramex = true;
        $("#checkout_form_address").on('submit', function(e) {
            if ($('#checkout_form_address').valid()) {
                var s_country = $("#order_ship_address_attributes_country_id").find('option:selected').attr('iso_code');
                var s_zipcode = $("#order_ship_address_attributes_zipcode").val();
                var s_city = $("#order_ship_address_attributes_city").val();
                var b_country = $("#order_bill_address_attributes_country_id").find('option:selected').attr('iso_code');
                var b_zipcode = $("#order_bill_address_attributes_zipcode").val();
                var b_city = $("#order_bill_address_attributes_city").val();
                if (call_aramex == true && (typeof aramex_countries !== 'undefined') && (aramex_countries.includes(b_country) || aramex_countries.includes(s_country))) {
                    e.preventDefault();
                    var error_id = $('#errorExplanation').is(':visible') ? '#errorExplanation' : '#manual_error'
                    $(error_id).html("").hide()
                    $.blockUI({
                        message: '<img src="/assets/ajax-loader.gif" />'
                    });
                    $.ajax({
                        url: "/api/validate_address_with_aramex",
                        type: 'GET',
                        dataType: "json",
                        data: {
                            s_country: s_country,
                            s_zipcode: s_zipcode,
                            s_city: s_city,
                            b_country: b_country,
                            b_zipcode: b_zipcode,
                            b_city: b_city,
                            use_bill_address: ($("#order_use_billing").is(":checked"))
                        },
                        success: function(result) {
                            $.unblockUI()
                            if (result.b_errors || result.s_errors) {
                                if (result.b_errors) {
                                    $(error_id).append('<div>Billing Address ' + result.b_errors + ' </div>')
                                }
                                if (result.s_errors) {
                                    $(error_id).append('<div>Shipping Address ' + result.s_errors + ' </div>')
                                }
                                if ((result.b_errors && !result.s_errors) && ($("#order_use_billing").is(":unchecked"))) {
                                    $(".js-summary-edit").trigger("click")
                                }
                                $(error_id).show();
                                $('html, body').animate({
                                    scrollTop: '0px'
                                }, 300);
                            } else {
                                call_aramex = false;
                                $('#checkout_form_address').submit()
                            }
                        },
                        error: function(xhr, status, error) {
                            $(error_id).append('Oops Something Went Wrong but you can process order')
                            $(error_id).show();
                            $.unblockUI()
                            $('html, body').animate({
                                scrollTop: '0px'
                            }, 300);
                            $('#checkout_form_address').submit()
                        }
                    });
                }
            }
        })

        var getCountryId, order_use_billing, update_shipping_form_state;
        if (($('#checkout_form_address')).is('*')) {
            ($('#checkout_form_address')).validate({
                rules: {
                    "order[bill_address_attributes][city]": {
                        required: true,
                        maxlength: function(element) {
                            return maxCharLimit($("#order_bill_address_attributes_country_id").val(), 22)
                        }
                    },
                    "order[bill_address_attributes][firstname]": {
                        required: true,
                        maxlength: function(element) {
                            return maxCharLimit($("#order_bill_address_attributes_country_id").val(), 15)
                        }
                    },
                    "order[bill_address_attributes][lastname]": {
                        required: true,
                        maxlength: function(element) {
                            return maxCharLimit($("#order_bill_address_attributes_country_id").val(), 17)
                        }
                    },
                    "order[bill_address_attributes][address1]": {
                        required: true,
                        maxlength: function(element) {
                            return maxCharLimit($("#order_bill_address_attributes_country_id").val(), 32)
                        }
                    },
                    "order[bill_address_attributes][address2]": {
                        maxlength: function(element) {
                            return maxCharLimit($("#order_bill_address_attributes_country_id").val(), 32)
                        }
                    },
                    "order[bill_address_attributes][zipcode]": {
                        maxlength: function(element) {
                            return maxCharLimit($("#order_bill_address_attributes_country_id").val(), 10)
                        }
                    },
                    "order[ship_address_attributes][city]": {
                        required: true,
                        maxlength: function(element) {
                            return maxCharLimit($("#order_ship_address_attributes_country_id").val(), 22)
                        }
                    },
                    "order[ship_address_attributes][firstname]": {
                        required: true,
                        maxlength: function(element) {
                            return maxCharLimit($("#order_ship_address_attributes_country_id").val(), 15)
                        }
                    },
                    "order[ship_address_attributes][lastname]": {
                        required: true,
                        maxlength: function(element) {
                            return maxCharLimit($("#order_ship_address_attributes_country_id").val(), 17)
                        }
                    },
                    "order[ship_address_attributes][address1]": {
                        required: true,
                        maxlength: function(element) {
                            return maxCharLimit($("#order_ship_address_attributes_country_id").val(), 32)
                        }
                    },
                    "order[ship_address_attributes][address2]": {
                        maxlength: function(element) {
                            return maxCharLimit($("#order_ship_address_attributes_country_id").val(), 32)
                        }
                    },
                    "order[ship_address_attributes][zipcode]": {
                        maxlength: function(element) {
                            return maxCharLimit($("#order_ship_address_attributes_country_id").val(), 10)
                        }
                    }
                }
            });
            getCountryId = function(region) {
                return $('#' + region + 'country select').val();
            };

            isCountryUsOrCa = function(country_id) {
                return ["38", "232"].includes(country_id)
            }

            maxCharLimit = function(country_id, limit) {
                if (["38", "232"].includes(country_id)) {
                    return limit;
                } else {
                    return 255;
                }
            };

            Spree.updateState = function(region) {
                var countryId;
                var cityId
                countryId = getCountryId(region);
                if (countryId != null) {
                    if (region == 'b') {
                        cityId = '#order_bill_address_attributes_city'
                        countryInputId = "#order_bill_address_attributes_country_id"
                    } else {
                        cityId = '#order_ship_address_attributes_city'
                        countryInputId = "#order_ship_address_attributes_country_id"
                    }
                    fill_cities($(countryInputId).find('option:selected').attr('iso_code'), cityId)
                    if (Spree.Checkout[countryId] == null) {
                        return $.get(Spree.routes.states_search, {
                            country_id: countryId
                        }, function(data) {
                            Spree.Checkout[countryId] = {
                                states: data.states,
                                states_required: data.states_required
                            };
                            return Spree.fillStates(Spree.Checkout[countryId], region);
                        });
                    } else {
                        return Spree.fillStates(Spree.Checkout[countryId], region);
                    }
                }
            };

            fill_cities = function(country_code, cityId) {
                $.ajax({
                    url: "/api/fetch_cities_from_aramex_address",
                    type: 'GET',
                    dataType: "json",
                    data: {
                        country_code: country_code
                    },
                    success: function(data) {
                        $(cityId).autocomplete({
                            source: data,
                        });
                    },
                    error: function() {}
                });
            }

            Spree.fillStates = function(data, region) {
                var selected, stateInput, statePara, stateSelect, stateSpanRequired, states, statesRequired, statesWithBlank;
                statesRequired = data.states_required;
                states = data.states;
                statePara = $('#' + region + 'state');
                stateSelect = statePara.find('select');
                stateInput = statePara.find('input');
                stateSpanRequired = statePara.find('[id$="state-required"]');
                if (states.length > 0) {
                    selected = parseInt(stateSelect.val());
                    stateSelect.html('');
                    statesWithBlank = [{
                        name: '',
                        id: ''
                    }].concat(states);
                    $.each(statesWithBlank, function(idx, state) {
                        var opt;
                        opt = ($(document.createElement('option'))).attr('value', state.id).html(state.name);
                        if (selected === state.id) {
                            opt.prop('selected', true);
                        }
                        return stateSelect.append(opt);
                    });
                    stateSelect.prop('disabled', false).show();
                    stateInput.hide().prop('disabled', true);
                    statePara.show();
                    stateSpanRequired.show();
                    if (statesRequired) {
                        stateSelect.addClass('required');
                    }
                    stateSelect.removeClass('hidden');
                    return stateInput.removeClass('required');
                } else {
                    stateSelect.hide().prop('disabled', true);
                    stateInput.show();
                    if (statesRequired) {
                        stateSpanRequired.show();
                        stateInput.addClass('required');
                    } else {
                        stateInput.val('');
                        stateSpanRequired.hide();
                        stateInput.removeClass('required');
                    }
                    statePara.toggle(!!statesRequired);
                    stateInput.prop('disabled', !statesRequired);
                    stateInput.removeClass('hidden');
                    return stateSelect.removeClass('required');
                }
            };
            ($('#bcountry select')).change(function() {
                $('label.error').hide()
                if (isCountryUsOrCa($("#order_bill_address_attributes_country_id").val())) {
                    $('#checkout_form_address').valid();
                }
                return Spree.updateState('b');
            });
            ($('#scountry select')).change(function() {
                $('label.error').hide()
                if (isCountryUsOrCa($("#order_bill_address_attributes_country_id").val())) {
                    $('#checkout_form_address').valid();
                }
                return Spree.updateState('s');
            });
            Spree.updateState('b');
            order_use_billing = $('input#order_use_billing');
            order_use_billing.change(function() {
                return update_shipping_form_state(order_use_billing);
            });
            update_shipping_form_state = function(order_use_billing) {
                if (order_use_billing.is(':checked')) {
                    ($('#shipping .inner')).hide();
                    return ($('#shipping .inner input, #shipping .inner select')).prop('disabled', true);
                } else {
                    ($('#shipping .inner')).show();
                    ($('#shipping .inner input, #shipping .inner select')).prop('disabled', false);
                    return Spree.updateState('s');
                }
            };
            return update_shipping_form_state(order_use_billing);
        }
    };
    return Spree.onAddress();
});

为什么我会遇到顶部提到的问题?

4

2 回答 2

0

那么这里就是不断查找的问题。AramexAddressValidator由于您编写的方式而丢失的常量class Spree::Api::AramexAddressController < ApplicationController

因此,如果您的模块AramexAddressValidator在某个范围内,请在包含此模块的同时使用该范围。如果它在 spree/aramex_address_validator 内部使用 include Spree::AramexAddressValidator

于 2017-07-08T19:21:53.420 回答
0

也许你可以试试这个:

namespace :spree do namespace :api do resources :aramex_address, only: [] do get :validate_address_with_aramex get :fetch_cities_from_aramex_address end end end

建议的话我认为如果你重命名fetch_cities_from_aramex_addresswithshow方法会更好,所以它仍然遵循 Rails 的便利

于 2017-07-05T11:48:48.530 回答