, :foreign_key => :parent_id end

В отчете данные группировались по родительским объектам OfferDescription. Именно у объектов, у которых были дети, в отчетах были все нули. Рассчитывал отчеты приблизительно вот такой код.

    OfferDescription.scoped(:conditions => {:parent_id => nil}).find_in_batches do |batch|
      batch.each do |offer_description|
        if offer_description.children.present?
          # здесь считаем цифры по детям
        else
          # здесь просто считаем цифры
        end
      end
    end

Если бы я сразу прочитал первый комментарий на apidock.com для findinbatches, то сэкономил бы себе изрядное количество времени, но кто читает документацию, а тем более комментарии к ней?

Дело в том, что find_in_batches накладывает свои условия на все обращения к модели, из которой он вызван, внутри блока, который ему передан. То есть, в нашем примере, children.present? всегда будет возвращать false, потому что в выборку детей всегда будет добавляться условие :parent_id => nil.

Более того, следующий код тоже не будет работать (в примере взяты id, которые существуют в базе данных), потому что условия в запросе к БД никогда не выполняются.

    OfferDescription.scoped(:conditions => {:id => 16005}).find_in_batches do |batch|
      batch.each do |offer_description|
        OfferDescription.find 18847
        # здесь запрос к базе данных будет вот таким
        # SELECT * FROM "offer_descriptions" WHERE 
        # ("offer_descriptions"."id" = 18847) AND ("offer_descriptions"."id" = 16005)
      end
    end

Говоря откровенно, я не понимаю, зачем так сделано. Если кто-то объяснит мне тайный смысл этого в комментариях, я буду ему очень благодарен.

Все вышесказанное не умаляет полезности самого метода find_in_batches, потому что запросы к базе данных, которые он генерируют, позволяют выбрать все данные из базы, во многих случаях не создавая большую нагрузку. И конечно, он работает всегда не медленнее, чем постраничный перебор с использованием :limit и :offset.

' name='description'> , :foreign_key => :parent_id end

В отчете данные группировались по родительским объектам OfferDescription. Именно у объектов, у которых были дети, в отчетах были все нули. Рассчитывал отчеты приблизительно вот такой код.

    OfferDescription.scoped(:conditions => {:parent_id => nil}).find_in_batches do |batch|
      batch.each do |offer_description|
        if offer_description.children.present?
          # здесь считаем цифры по детям
        else
          # здесь просто считаем цифры
        end
      end
    end

Если бы я сразу прочитал первый комментарий на apidock.com для findinbatches, то сэкономил бы себе изрядное количество времени, но кто читает документацию, а тем более комментарии к ней?

Дело в том, что find_in_batches накладывает свои условия на все обращения к модели, из которой он вызван, внутри блока, который ему передан. То есть, в нашем примере, children.present? всегда будет возвращать false, потому что в выборку детей всегда будет добавляться условие :parent_id => nil.

Более того, следующий код тоже не будет работать (в примере взяты id, которые существуют в базе данных), потому что условия в запросе к БД никогда не выполняются.

    OfferDescription.scoped(:conditions => {:id => 16005}).find_in_batches do |batch|
      batch.each do |offer_description|
        OfferDescription.find 18847
        # здесь запрос к базе данных будет вот таким
        # SELECT * FROM "offer_descriptions" WHERE 
        # ("offer_descriptions"."id" = 18847) AND ("offer_descriptions"."id" = 16005)
      end
    end

Говоря откровенно, я не понимаю, зачем так сделано. Если кто-то объяснит мне тайный смысл этого в комментариях, я буду ему очень благодарен.

Все вышесказанное не умаляет полезности самого метода find_in_batches, потому что запросы к базе данных, которые он генерируют, позволяют выбрать все данные из базы, во многих случаях не создавая большую нагрузку. И конечно, он работает всегда не медленнее, чем постраничный перебор с использованием :limit и :offset.

' property='og:description'> , :foreign_key => :parent_id end

В отчете данные группировались по родительским объектам OfferDescription. Именно у объектов, у которых были дети, в отчетах были все нули. Рассчитывал отчеты приблизительно вот такой код.

    OfferDescription.scoped(:conditions => {:parent_id => nil}).find_in_batches do |batch|
      batch.each do |offer_description|
        if offer_description.children.present?
          # здесь считаем цифры по детям
        else
          # здесь просто считаем цифры
        end
      end
    end

Если бы я сразу прочитал первый комментарий на apidock.com для findinbatches, то сэкономил бы себе изрядное количество времени, но кто читает документацию, а тем более комментарии к ней?

Дело в том, что find_in_batches накладывает свои условия на все обращения к модели, из которой он вызван, внутри блока, который ему передан. То есть, в нашем примере, children.present? всегда будет возвращать false, потому что в выборку детей всегда будет добавляться условие :parent_id => nil.

Более того, следующий код тоже не будет работать (в примере взяты id, которые существуют в базе данных), потому что условия в запросе к БД никогда не выполняются.

    OfferDescription.scoped(:conditions => {:id => 16005}).find_in_batches do |batch|
      batch.each do |offer_description|
        OfferDescription.find 18847
        # здесь запрос к базе данных будет вот таким
        # SELECT * FROM "offer_descriptions" WHERE 
        # ("offer_descriptions"."id" = 18847) AND ("offer_descriptions"."id" = 16005)
      end
    end

Говоря откровенно, я не понимаю, зачем так сделано. Если кто-то объяснит мне тайный смысл этого в комментариях, я буду ему очень благодарен.

Все вышесказанное не умаляет полезности самого метода find_in_batches, потому что запросы к базе данных, которые он генерируют, позволяют выбрать все данные из базы, во многих случаях не создавая большую нагрузку. И конечно, он работает всегда не медленнее, чем постраничный перебор с использованием :limit и :offset.

' property='twitter:description'>

Технические заметки одного Евтуховича

Рассказ о серых трудовых буднях инженера программных систем

Проблемы с find_in_batches

| Комментарии

Иногда мне кажется, что большинство инженерных историй похожи как две капли воды. Вот и эта история началась с того, что в одном большом отчете цифры не сходились раза в два.

Мысленно закурив трубку, как Шерлок Холмс, я взялся за дело. Вот таким образом выглядела модель, по которой считались цифры (я опускаю ненужные подробности).

    class OfferDescription < ActiveRecord::Base
      has_many :children, :class_name => 'OfferDescription', :foreign_key => :parent_id
    end

В отчете данные группировались по родительским объектам OfferDescription. Именно у объектов, у которых были дети, в отчетах были все нули. Рассчитывал отчеты приблизительно вот такой код.

    OfferDescription.scoped(:conditions => {:parent_id => nil}).find_in_batches do |batch|
      batch.each do |offer_description|
        if offer_description.children.present?
          # здесь считаем цифры по детям
        else
          # здесь просто считаем цифры
        end
      end
    end

Если бы я сразу прочитал первый комментарий на apidock.com для findinbatches, то сэкономил бы себе изрядное количество времени, но кто читает документацию, а тем более комментарии к ней?

Дело в том, что find_in_batches накладывает свои условия на все обращения к модели, из которой он вызван, внутри блока, который ему передан. То есть, в нашем примере, children.present? всегда будет возвращать false, потому что в выборку детей всегда будет добавляться условие :parent_id => nil.

Более того, следующий код тоже не будет работать (в примере взяты id, которые существуют в базе данных), потому что условия в запросе к БД никогда не выполняются.

    OfferDescription.scoped(:conditions => {:id => 16005}).find_in_batches do |batch|
      batch.each do |offer_description|
        OfferDescription.find 18847
        # здесь запрос к базе данных будет вот таким
        # SELECT * FROM "offer_descriptions" WHERE 
        # ("offer_descriptions"."id" = 18847) AND ("offer_descriptions"."id" = 16005)
      end
    end

Говоря откровенно, я не понимаю, зачем так сделано. Если кто-то объяснит мне тайный смысл этого в комментариях, я буду ему очень благодарен.

Все вышесказанное не умаляет полезности самого метода find_in_batches, потому что запросы к базе данных, которые он генерируют, позволяют выбрать все данные из базы, во многих случаях не создавая большую нагрузку. И конечно, он работает всегда не медленнее, чем постраничный перебор с использованием :limit и :offset.

Комментарии