Сбой сервера Rails с несколькими вызовами js

1

Я создаю гибкую функцию отчетности как часть более крупного проекта. Отдельная часть, с которой я борюсь, прекрасно работает для нескольких вызовов, а затем приводит к сбою сервера. Я использую mongoid и puma server - пожалуйста, дайте мне знать, если есть дополнительная информация, которую я могу предоставить.

Проделали целую серию поисков - на самом деле это было неудобно. Заранее спасибо!

Сообщение об ошибке консоли Это только первая часть ошибки - она идет на нескольких страницах, давая "Информация о контрольном кадре", "Другая информация о времени выполнения" и "Карта памяти процесса",

/usr/local/rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/forwardable.rb:228: [BUG] Segmentation fault at 0x00000000000038
ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-linux]

Соответствующий скрипт страницы js хранит значение поля категории и выталкивает все выбранные значения столбцов (в пределах мультиселективной формы) в массив и отправляет обе переменные в действие контроллера get_filter_columns

<script>
    $(document).ready(function(){
        function get_filter_columns(filter_columns, category){
          $.get('reports/get_filter_columns',{filter_columns, category});
        };

        $(document).on('change', "#filter_columns", function() {
            var filter_column_array = [];
            var category = $("#report_category").val();
            $("#filter_columns .box2 option").each(function() {

                filter_column_array.push($(this).val());
            });
            get_filter_columns(filter_column_array, category);
        });  
   });
</script>

_filter_columns.html.erb, который отвечает на событие onchange js

<div id = "filter_columns" class="col-lg-5">
    <div class = "ibox-content report_builder_body">
        <h2>Filter Columns</h2>
        <%= simple_fields_for :filter_columns_nested_form do |ff| %>
            <%= ff.select( :filter_columns, (@category || Account).attribute_names.map{ |value| [value.to_s.underscore.humanize, value] }, {}, { :id => "filter_columns", :class => "form-control dual_select_filter_columns", :multiple => true })  %>
        <% end %>
    </div>
</div>

reports_controller.rb Действие контроллера, вызываемое js

    def get_filter_columns

        @category = (params[:category] || "Account").split(' ').collect(&:capitalize).join.constantize

        @filter_categories = (params[:filter_columns] || []).map{ |filter| filter }

        @filter_symbols = {}

        @filter_logic = ["Equal to", "Not equal to", "Less than", "Less than or equal to", "Greater than", "Greater than or equal to", "Is between", "Is not between"]

        @filter_categories.each do |fs|
          if @category.instance_methods(false).include?(fs.to_s.to_sym) == true
            @filter_symbols[fs] = "enum"
          elsif @category.pluck(fs.to_s.to_sym)[0].class.to_s == "BSON::ObjectId"
            @filter_symbols[fs] = "string"
          elsif @category.pluck(fs.to_s.to_sym)[0].class.to_s == "NilClass"
            @filter_symbols[fs] = "string"
          elsif @category.pluck(fs.to_s.to_sym)[0].class.to_s == "Time"
            @filter_symbols[fs] = "date"
          else
            @filter_symbols[fs] = @category.pluck(fs.to_s.to_sym)[0].class.to_s || "string"
          end
        end

        render "reports/js_templates/get_filter_columns.js.erb"
    end

Шаблон get_filter_columns.js.erb js обрабатывается действием контроллера get_filter_columns

$('#filters').replaceWith('<%= j render("reports/partials/filters") %>');

_filters.html.erb, частично отображаемый файлом get_filter_columns.js.erb

<div class="col-lg-7" id = "filters">
    <div class = "ibox-content report_builder_body">
        <h2>Filter Criteria</h2>
        <div class="scroll_content">
            <% if @filter_categories.nil? || @filter_categories.size == 0 %>
                <p> No filter columns have been selected! </p>
            <% else %>
                <%= simple_fields_for :filters_nested_form do |ff| %>
                    <% (@filter_categories || []).each do |filter| %>
                        <div class = "col-lg-3"> 
                            <h5>
                                <%= filter.to_s.underscore.humanize %>:
                            </h5>    
                        </div>
                        <%= ff.simple_fields_for :"#{filter}" do |fff| %>
                            <div class = "col-lg-5">
                                <%= fff.input :logic, collection: @filter_logic, label: false %>
                            </div> 
                            <div class = "col-lg-4">
                                <%= fff.input :criteria, as: :"#{@filter_symbols[filter].to_s.downcase}", label: false %>
                            </div>   
                        <% end %>    
                    <% end %>
                <% end %>
            <% end %>
        </div>
    </div>    
</div>

2 ответа

0
Лучший ответ

Кажется, что проблема вызвана вызовом методов.class и.instance_methods в быстрой последовательности через js. Я удалил методы.class и.instance_methods из действия контроллера и не имел проблемы с тех пор.

Я решил проблему путем компиляции вложенного хеша при начальной загрузке страницы (формат показан ниже). Затем хэш возвращается к действию контроллера get_filter_columns, чтобы избежать воссоздания хэша и необходимость вызова проблемных методов внутри контроллера.

column_symbols = { model_1_name: { column_1_name: data_type, column_2_name: data_type }, model_2_name: { column_1_name: data_type, column_2_name: data_type }..... } 
0

Это может помочь ошибке, в коде контроллера сделать это, это по крайней мере предотвратит несколько попыток нескольких ударов БД несколько раз подряд.

ClassOverrideList = {
  "BSON::ObjectId" => "string",
  "NilClass" => "string",
  "Time" => "date"          
}

def get_filter_columns

    @category = (params[:category] || "Account").split(' ').collect(&:capitalize).join.constantize

    @filter_categories = (params[:filter_columns] || []).map{ |filter| filter }

    @filter_symbols = {}

    @filter_logic = ["Equal to", "Not equal to", "Less than", "Less than or equal to", "Greater than", "Greater than or equal to", "Is between", "Is not between"]

    @filter_categories.each do |fs|
      fs_sym = fs.to_s.to_sym
      if @category.instance_methods(false).include?(fs.to_s.to_sym) == true
        @filter_symbols[fs] = "enum"
      else
        category_class = @category.pluck(fs_sym)[0].class.to_s
        @filter_symbols[fs] = ClassOverrideList[category_class] ||
          category_class ||
          "string"
      end
    end

    render "reports/js_templates/get_filter_columns.js.erb"
end

Ещё вопросы

Сообщество Overcoder
Наверх
Меню