을이 당신이 협회를 참조하고 있기 때문에 orders.count
대신 order.count
을 사용해야합니다 설치 프로그램을 가지고있는 것처럼하려면. 그러면 ActiveRecord가 SELECT COUNT(*) FROM orders WHERE delivery_slot_id = 1
과 비슷한 쿼리를 조합합니다.
레일스는 적절하게 패스 할 때 where
조건에서 하위 쿼리로 사용하기에 실제로 똑똑합니다 (la where('limit > ', orders.count)
). 그러나 쿼리가 조건에서 명시적인 ID를 사용하기 때문에 사전 컴파일 된 경우이 방법이 작동하지 않습니다.
대신에 모호한 조건으로 주문을 계산 한 다음 서브 쿼리로 사용하십시오 : where('limit > ?', Order.where(delivery_slot_id: 'delivery_slots.id').count)
. 자체적으로 주문 수에 대한 쿼리를 실행하려고 시도하면 delivery_slots
에서 실패하지만 하위 쿼리에 있기 때문에 원활한 항해가 이루어져야합니다.
는
나는 카운터 캐시를 사용하지만 모두이 일을 다른 방법을 제안하고 싶습니다 :이 색인 있기 때문에
class AddCounterCacheToDeliverySlots < ActiveRecord::Migration
class DeliverySlot < ActiveRecord::Base; end
def change
add_column :delivery_slots, :orders_count, :integer, default: 0
add_index :delivery_slots, [:orders_count, :limit]
DeliverySlot.reset_column_information
DeliverySlot.find_each do |delivery_slot|
DeliverySlot.update_counters delivery_slot.id, orders_count: delivery_slot.orders.count
end
end
end
class Order < ActiveRecord::Base
belongs_to :delivery_slot, counter_cache: true
end
class DeliverySlot < ActiveRecord::Base
has_many orders
scope :available, where('orders_count < limit')
end
레일이 자동으로 증가하고 각 DeliverySlot
에 대한 orders_count
열을 감소하고, 것, 그것은 터무니입니다 빠른 쿼리.
와우, 고마워. 나는 카운터 캐시에 대해 몰랐다. 나는 지금 그것을 구현했습니다. –
@ MarkRobinson 이봐, 나는 당신이 제안한 편집을 보았고, 나는'class DeliverySlot
coreyward