2015-09-22 70 views
0

所以我有一點服務器響應時間問題 - 我認爲這是由於過時的查詢造成的。我有一個主要的查詢鏈需要370ms,這顯然是一個問題。有效地查詢多語言類別和類別項目

這裏是要求:

  1. 5種不同語言
  2. 有幾個產品類別(即第1類,2類,3類,等等)顯示
  3. 分類取決於語言。例如,雖然類別1以所有語言顯示,但類別2僅顯示在德國和法國,但不顯示在英國
  4. 每個類別包含x個項目(has_many belongs_to關係)。有些項目再次以某些語言顯示,其他項目則不是。例如,即使類別2顯示在法國和德國,只有在德國,您可以購買第1項,因此第1項不應顯示在法國,而是德國。
  5. 類別和項目確實具有以區域設置命名的布爾字段。通過這種方式,我可以通過標誌來設置是否使用特定語言顯示類別和項目。

我的解決辦法:

構建解決方案是安靜容易。在控制器我讀了所有的類別當前語言環境:

application_controller.rb(因爲它是每一個頁面上使用)


@product_categories = ProductCategory.where("lang_" + I18n.locale.to_s + " = ?", true) 

並在視圖(導航)我做了以下操作:

layouts/navs/productnav.html.haml


- @product_categories.each do |category| 
    ... 
    - category.products.includes(:product_teasers).where("lang_" + I18n.locale.to_s + " = ? AND active = ?", true, true).in_groups_of(3).each do |group| 
    ... 

這種解決方案的問題是,每次我火了很多對數據庫的查詢。使用「包含」不能解決它,因爲我不能指定要拉什麼項目。此外,我需要我的循環中的in_groups_of(3)在頁面上正確顯示項目。

我還在研究memchached解決方案,將查詢緩存在一起 - 即Dalli但是,這需要我更改很多代碼,因爲我猜測我需要查詢每種語言的所有類別並緩存它們。除此之外,我必須根據語言查詢每個語言的每個項目,並以某種方式存儲在數組中?!

我的問題:

如何處理呢?必須有一個更簡單,更有效的解決方案。如何高效查詢分別緩存這個?

謝謝!

UPDATE:

如這裏要求是我的兩個型號:

1)產品分類

class ProductCategory < ActiveRecord::Base 
    translates :name, :description, :slug, :meta_keywords, :meta_description, :meta_title, :header, :teaser, :fallbacks_for_empty_translations => true 
    extend FriendlyId 
    friendly_id :name, :use => [:globalize, :slugged] 
    globalize_accessors :locales => [:at, :de, :ch_de, :ch_fr, :fr, :int_en, :int_fr], :attributes => [:slug] 

    has_paper_trail 
    has_many :products, :dependent => :destroy 

    validates :name, presence: true, uniqueness: { case_sensitive: false } 
    default_scope { includes(:translations) } 

    private 
    def slug_candidates 
    [ 
     [:name] 
    ] 
    end 
end 

2)產品 一個產品類別可以有0到n產品和每個產品必須屬於一個類別。

class Product < ActiveRecord::Base 
    translates :slug, :name, :meta_keywords, :meta_description, :meta_title, :teaser, :power_range, :product_page_teaser, :product_category_slider_teaser, :fallbacks_for_empty_translations => true 
    extend FriendlyId 
    friendly_id :name, :use => :globalize 

    before_save :change_file_name 

    searchable do 
    text :name, :teaser, :product_page_teaser, :product_category_slider_teaser 
    integer :product_category_id 
    end 

    belongs_to :product_category 
    has_many :product_teasers, :dependent => :destroy 
    has_many :product_videos, :dependent => :destroy 
    has_many :product_banners, :dependent => :destroy 
    has_many :product_documents, :dependent => :destroy 
    has_many :product_tabs, :dependent => :destroy 
    has_many :active_relationships, class_name: "Relationship", 
      foreign_key: "follower_id", 
      dependent: :destroy 
    has_many :passive_relationships, class_name: "Relationship", 
      foreign_key: "followed_id", 
      dependent: :destroy 
    has_many :following, through: :active_relationships, source: :followed 
    has_many :followers, through: :passive_relationships, source: :follower 
    has_many :references 

    has_and_belongs_to_many :contacts 

    accepts_nested_attributes_for :product_teasers, :reject_if => :all_blank, :allow_destroy => true 
    accepts_nested_attributes_for :product_tabs, :reject_if => :all_blank, :allow_destroy => true 
    accepts_nested_attributes_for :product_videos, :reject_if => :all_blank, :allow_destroy => true 
    accepts_nested_attributes_for :product_banners, :reject_if => :all_blank, :allow_destroy => true 
    accepts_nested_attributes_for :product_documents, :reject_if => :all_blank, :allow_destroy => true 

    has_paper_trail 
    validates :name, presence: true, uniqueness: { case_sensitive: false } 
    default_scope {includes(:translations)} 

    .... a lot more going on here ... 

end 

請注意:類別包含語言標誌(布爾),即lang_at,lang_de,lang_fr等,如果設置則該類別顯示在particualar語言。同樣適用於產品,因爲某些產品不會在所有語言中顯示,儘管該類別可能是。

實例:

@product_categories = ProductCategory.where("product_categories.lang_" + I18n.locale.to_s + " = ?", true) 

@products = Product.where("product_categories.lang_" + I18n.locale.to_s + " = ?", true) 

我跳過上目的的任何包括以上 - 它只是以展示語邏輯。

+0

你能展示模型嗎?我需要知道你的關聯。 – akbarbin

回答

0

UPDATE

該系統已在嵌套循環花費了大量的時間循環的數據。避免在嵌套循環中獲取數據。您必須使用加入或包含才能更有效地捕捉數據。例如:

控制器

@products = Product.includes(:product_category).where("product_categories.lang_" + I18n.locale.to_s + " = ? AND product_categories.active = ?", true, true).group_by(&:category) 

查看

- @products.each do |category, products| 
    <%= category.name %> 
    - products.each do |product| 
    <%= product.title %> 

它需要與必要的代碼來解決。我只是幫助主查詢。例如:active = ?用於產品字段或產品類別字段。我希望它可以幫助你。

+0

嗨,穆罕默德,對不起,以前沒有看到你的回覆。我將很快用我的模型更新我的問題 - 我之前嘗試過這種方法,但是由於類別和產品本身都是依賴於語言的,因此我的連接看起來非常失敗。無論如何,將很快更新,謝謝! –

+0

沒關係。當你完成更新時,請告訴我。 – akbarbin

+0

添加模型:) –

相關問題