ben

OMÜ , Bilgisayar Mühendisliği, 13'

23 Kasım 2015 Pazartesi

bullet gem

    ilişkili tablolar arasında veri dolaşımı yaparak veri getirdiğimizde n+1 tarzı problemler oluşabilir. bullet  gemi bunun önüne geçer.

Kullanımı:

gemfile
 
      gem "bullet", :group => "development"

config/environments/development.rb

  config.after_initialize do
     Bullet.enable = true
     Bullet.alert = true
     Bullet.bullet_logger = true
     Bullet.console = true
     Bullet.growl = true
     Bullet.rails_logger = true
     Bullet.add_footer = true
  end

Category modelimiz ve lesson modelimiz var, Category, ders modeline has_many olarak bağlı.


Lesson modeline ait index sayfasında verileri listelerken hangi kategoride olduğunuda göstermek istediğimde lesson.category.name demem yeterli olur, fakat tamda bu noktada N+1 problemi oluşuyor. Her bir lesson satırı için categori tablosuna gidip geliyor. Bu da haliyle performans ve işlem hızınının düşmesine sebep oluyor. rails c ile çalıştırdığımızda bullet gemi işini yapıp bizi uyarıyor.


Gelelim Çözüme:

 lesson_controller.rb

    def index
         #before
          @lessons=Lesson.all
         #after
          @lessons=Lesson.includes(:category)
    end

Tekrar çalıştıralım:



Bu durumun bir de tersi var . biz N+1 in önüne geçelim diye controllere include ekledik, fakat view de lesson.category diyerek veri almadık.



 bu seferde gereksiz yere include kullandın diye hata verir.




Bulletin bir diğer güzel özelliği cache ;

Diyelimki category'lerde kayıtlı ders sayısını istedik, Klasik olarak yapacağımız şey  category.lessons.size!!

categories_controller.rb

    def index
       @categories=Category.all
    end

view


Çalıştırıp hatayı alalım:

 lesson.rb
belongs_to :category, counter_cache: true


terminal:
   rails g migration add_lessons_count_to_categories lessons_count:integer
 
AddLessonsCountToCategories dosyasını duzenleyelim:

  def change
    add_column :categories, :lessons_count, :integer, default:0,null:false
  end

terminal:

rails g migration cache_lessons_count


class CacheLessonsCount dosyasını duzenleyelim

  def up
  execute "update categories set lessons_count=(select count(*) from lessons where category_id= categories.id)"
  end
  def down
  end
end

terminal:

rake db:migrate



Artık uyarı vermiyor :D