支持,我有兩個模型項目和類別分類,在許多一對多的關係ActiveRecord的發現包含至少一個項目
class Item < ActiveRecord::Base
has_and_belongs_to_many :categories
class Category < ActiveRecord::Base
has_and_belongs_to_many :items
現在我想篩選出其中至少包含一個項目類別,最好的辦法是什麼?
支持,我有兩個模型項目和類別分類,在許多一對多的關係ActiveRecord的發現包含至少一個項目
class Item < ActiveRecord::Base
has_and_belongs_to_many :categories
class Category < ActiveRecord::Base
has_and_belongs_to_many :items
現在我想篩選出其中至少包含一個項目類別,最好的辦法是什麼?
請注意,其他人answererd是不是表演!
最高效的解決方案:
更好的工作與counter_cache並保存items_count模型!
scope :with_items, where("items_count > 0")
has_and_belongs_to_many :categories, :after_add=>:update_count, :after_remove=>:update_count
def update_count(category)
category.items_count = category.items.count
category.save
end
正常 「belongs_to的」 關係你只寫
belongs_to :parent, :counter_cache=>true
,並在parent_model你有一個場items_count(項目是多元化的的has_many類名)
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
在has_and_belongs_to_many關係中,你必須按照你自己的方式寫出它
Category.joins(:items)
更多細節在這裏:http://guides.rubyonrails.org/active_record_querying.html#joining-tables
scope :has_item, where("#{table_name}.id IN (SELECT categories_items.category_id FROM categories_items")
這將返回其具有在連接表項的所有類別,因爲表面上,一類不應該有一個入口那裏,如果它沒有一個物品。您可以將AND categories_items.item_id IS NOT NULL
添加到子選擇條件中以確保。
如果您不知道,table_name
是返回調用它的ActiveRecord類的表名稱的方法。在這種情況下,它將是"categories"
。
我想回應@ Delba的回答,並對其進行擴展,因爲它是正確的 - 如果你的索引設置正確,@huan兒子建議的count列是完全不必要的。
我想補充一點,你可能想使用.uniq,因爲它是一個多到許多你只是想不同的類別回來:
Category.joins(:items).uniq
使用聯接查詢將讓你更輕鬆地工作將項目數量也考慮在內,給予更多的靈活性。例如,你可能不希望清點貨物,其中啓用=假:
Category.joins(:items).where(:items => { :enabled => true }).uniq
這將生成的SQL語句,使用內部聯接這是非常快:
SELECT `categories`.* FROM `categories` INNER JOIN `categories_items` ON `categories_items`.`category_id` = `categories`.`id` INNER JOIN `items` ON `items`.`id` = `categories_items`.`item_id` WHERE `items`.`enabled` = 1
祝你好運, 斯圖
它可能性能較差,但它依賴於RDBMS來保持一致性(它們專門爲此設計的)。根據Rails如何執行after_add回調(例如,它是否在事務中),最終可能導致計數不一致。 – ahlatimer
您可以爲這些案例編寫測試,並將事務包裝在其中。那不是問題。但事實上:你有2500個類別,裏面都有10-500篇文章。你知道查詢有多大嗎? :) –
你知道查詢有多大嗎?內部加入速度非常快,即使對於數千條記錄,您的保存也很少。並且您正在假設類別和項目被插入/添加的次數與它們被選擇的次數之間的關係。所以它*可能不會更高性能 – Stu