一個視頻可以有多個類別。
video.rb
has_many :video_categories
has_many :categories, through: :video_categories
category.rb
has_many :video_categories
has_many :videos, through: :video_categories
我有一個簡單的表單,允許用戶選擇他想要組合的類別以查找特定視頻。例如,有一個“python”類別和“高級”類別。如果他選擇了這兩個類別,它應該顯示同時具有這兩個類別的視頻。
視頻 A - 類別 [1,4,7](這是類別 ID)
視頻 B - 類別 [1,2,7,9]
視頻 C - 類別 [7,9]
如果用戶選擇類別 [1,7],則輸出應為視頻 A 和 B。我回傳的當前范圍是所有類別為 1 的視頻、類別為 7 的所有視頻以及同時包含這兩個類別的視頻。
我只想要同時包含兩者的視頻。我怎么做 ?
當前范圍:
video.rb
scope :for_categories, -> (category_ids) {
joins(:video_categories).where(
video_categories: { category_id: category_ids }
)
}
pages_controller.rb
def search
@results = Video.for_categories(params[:category_ids])
end
我的表格
<%= form_with url: "/search", method: :get do |form| %>
<%= form.collection_check_boxes(:category_ids, Category.all,
:id, :title, { prompt: 'None'}, { multiple: true} ) do |cat| %>
<label class="text-capitalize checkbox-inline mr-2">
<%= cat.check_box %>
<%= cat.label %>
</label>
<% end %>
<%= form.submit "Search" %>
<% end %>
uj5u.com熱心網友回復:
我能夠使用以下代碼找到解決方案
video.rb
scope :by_categories, -> (category_ids) {
joins(:categories).where(categories: [category_ids] )
}
scope :by_all_categories, -> (category_ids) {
by_categories(category_ids).
group("videos.id").
having('count(videos.id) >= ?', category_ids.size)
}
pages_controller.rb
def search
@results = Video.by_all_categories(params[:category_ids].reject(&:empty?))
end
uj5u.com熱心網友回復:
你想應用一個 GROUP 并使用 HAVING 來設定組的條件,以確保加入的類別數量與 id 數量匹配:
class Video
def self.for_categories(*category_ids)
ids = category_ids.flatten # handles a single array as input
group(:id)
.joins(:categories)
.where(categories: { id: ids })
.having(
Category.arel_table[:id]
.count
.gteq(ids.length)
)
end
end
就 SQL 而言,這會給你類似的東西:
SELECT videos.*
FROM videos
INNER JOIN video_categories ON video_categories.video_id = videos.id
INNER JOIN categories ON video_categories.category_id = categories.id
WHERE categories.id IN (1, 2, 3)
GROUP BY videos.id
HAVING COUNT(categories.id) >= 3
uj5u.com熱心網友回復:
categories_to_search = [1, 7]
conditions = categories_to_search.map do |c|
{ viedo_categories: { category_id: c } }
do
Video.where conditions
# this is the same as: Video.where viedo_categories: { category_id: 1 }, viedo_categories: { category_id: 7 }
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/317059.html
下一篇:.net中對單例物件的多次訪問
