0

Productは多くのモデルを持っていItemsます。アプリケーションは、製品に属する固有のアイテムをリストします。したがって、アイテムは在庫と考えてください。次のクエリは、製品の注目のアイテムを取得し、最初のアイテムを削除します (関連性はありませんが、興味がある場合は、それが注目のアイテムになり、個別に表示されます)。

# product.rb
has_many :items_in_stock, -> { Item.in_stock }, class_name: 'Item'
def featured_items
  items_in_stock.select("DISTINCT ON (condition) id, items.*")
    .order(:condition, :price)
    .sort_by { |item| item[:price] }[1..-1]
end

# item.rb
scope :in_stock, -> { where(status: 'in_stock') }

問題は、feaured_itemsが空の場合、メソッドはリレーション オブジェクトではなく nil を返すことです。@product.featured_items.any?これは、アイテムのない製品を呼び出すとエラーが発生することを意味します。ブロックを削除するとsort_by、空のリレーション オブジェクトが得られます。

これ以外にこれを処理する良い方法はありますか:

items = items_in_stock.select("DISTINCT ON (condition) id, items.*").order(:condition, :price)
if items.any?
  items.sort_by { |item| item[:price] }[1..-1]
end

order by ステートメントの条件の順序がグループ条件と一致する必要があるというエラーが表示されるため、クエリの順序を逆にすることはできません。

4

2 に答える 2

3

私は混乱しています...ルビーのように扱われる.any?ので、なぜそれを呼び出すのですか。返されたものがである場合は、注目のアイテムがないことがわかります。nilfalsenil

私はこれを実行しましたirbが、あなたの問題は [1..-1] だと思います。

a = []
# => []
a.sort_by { |w| w.length }
# => []
a.sort_by { |w| w.length }[1..-1]
# => nil

最も簡単な方法は、単に行うことです

items = items_in_stock.select("DISTINCT ON (condition) id, items.*")
  .order(:condition, :price)
  .sort_by { |item| item[:price] }
items.any? ? items[1..-1] : items

そうすれば、必要でない限り、実際にコードの他の部分をチェックする必要はありません。

于 2013-07-15T23:38:31.570 に答える