44004


データの並び替えをしたいのですが、メソッドで得た値を並び替えることはできるでしょうか？

例えば商品（products）がどれだけ売れたか何ですが、商品の売れた数（quantity）を持っているのは中間テーブルの（line_items）というものです。なので、line_itemsがたくさんある中で特定のproductを持つline_itemのquantityを集計したものが該当します。自分はこれをtotal_countというメソッドでproduct.rbとline_item.rbに追加しました。

[code]

    # total_countの中身
    line_items.to_a.sum { |item| item.quantity } 
    
[/code]

そこで質問なのですが、上記で得られる値を並び替えたりすることはできるでしょうか？

カラムの値を並び替えるのはできたのですが、複数の値を集計してある値の並び替えが全くうまくできませんでした。

こちら何かアドバイスいただけたら助かります。こう書いたらいいとか、そもそもそれじゃできない等。。。

以上ですよろしくお願いしますm(._.)m

☆追記

[code]

    class LineItem < ApplicationRecord
        belongs_to :order
        belongs_to :product
        belongs_to :cart
    
        def total_price
            product.price * quantity
        end
    end
    
[/code]

と

[code]

    class Product < ApplicationRecord
    has_many :line_items
    has_many :orders, through: :line_items
    has_many :users
    
    belongs_to :category
    
    validates :image_url, presence: true
    validates :title, :description, presence: true
    validates :price, numericality: {greater_than_or_equal_to: 0.01}
    validates :title, uniqueness: true
    
    scope :get_by_name, ->(title){
        where('title like ?',"%#{title}%")
    }
    
    
    def total_count
        line_items.to_a.sum { |item| item.quantity} 
    end
    
[/code]

end

と

[code]

    class Order < ApplicationRecord
        PAYMENT_TYPES = ["現金","クレジットカード","注文書"]
        has_many :line_items, dependent: :destroy
        has_many :order_items, dependent: :destroy
    
        belongs_to :user
    
    
        validates :name, :address, :email,:user_id, presence: true
        validates :pay_type, inclusion: PAYMENT_TYPES
    
        default_scope -> { order(created_at: :desc) }
    
        def add_line_items_from_cart(cart)
            cart.line_items.each do |item|
                item.cart_id = nil
                line_items << item
            end
        end
        def total_price
            line_items.to_a.sum { |item| item.total_price }
        end
        def total_count
            line_items.to_a.sum { |item| item.quantity}
        end
    end
    
[/code]

と

[code]

    ActiveRecord::Schema.define(version: 20180508113923) do
      create_table "carts", force: :cascade do |t|
        t.datetime "created_at", null: false
        t.datetime "updated_at", null: false
      end
    
      create_table "line_items", force: :cascade do |t|
        t.integer "product_id"
        t.integer "cart_id"
        t.datetime "created_at", null: false
        t.datetime "updated_at", null: false
        t.integer "quantity", default: 1
        t.integer "order_id"
      end
    
      create_table "orders", force: :cascade do |t|
        t.string "name"
        t.text "address"
        t.string "email"
        t.string "pay_type"
        t.datetime "created_at", null: false
        t.datetime "updated_at", null: false
        t.integer "user_id"
        t.integer "product_id"
        t.integer "quantity"
      end
    
      create_table "products", force: :cascade do |t|
        t.string "title"
        t.text "description"
        t.string "image_url"
        t.decimal "price", precision: 8, scale: 2
        t.datetime "created_at", null: false
        t.datetime "updated_at", null: false
        t.string "category_id"
      end
    end
    
[/code]

です。

やりたいことは、最初に書いたようにメソッドで引き出したデータの並び替えです。total_countというメソッドでline_items（カートの中の商品兼購入された商品）の中の（商品）productと（注文数）quantityを計算して１つのproductがどのくらいquantityを持っているかを計算して出すところまではできたのですが、この引き出せた値を多い順に並び替え、すなわちline_itemsの中のproduct,の中で購入されたものが多い順に並び替えたいのです。説明が下手ですみません。

viewでeach使ってproduct.order("total_count
desc").limit(5)とかでできるかとも思ったのですがうまくいきませんでした。そもそも.order("メソッド”)てのが使えないんじゃないかとも思い手詰まりになったので質問に至りました。

宜しくお願いしますm(._.)m


CC BY-SA 4.0
2018-05-12T05:05:53.827
43931
2018-05-15T10:40:13.130
2018-05-15T08:51:01.030
76
27359
question
ruby-on-rails ruby
メソッドで得た値の並び替え


@豚吐露 さんが書かれているように`sort_by`でも処理速度に問題がなければいいのですが、  
`sort_by`は`Array`のメソッドですので`ActiveRecord::QueryMethods`のメソッドを使った方が`SQL`での処理になるため速度面など色々と都合が良いです。

[code]

    class Product < ApplicationRecord
      has_many :line_items
    
      def total_count
        line_items.to_a.sum { |item| item.quantity} 
      end
    end
    
    product.order("total_count desc").limit(5)
    
[/code]

でしたかったことは以下のコードでできるかと思いますが、これ`Order`クラスを使ってませんがいいんでしょうか。

[code]

    Product.joins(:line_items).group(:id).order('SUM(line_items.quantity) DESC').limit(3)
    
[/code]


CC BY-SA 4.0
2018-05-15T10:40:13.130
44004
2018-05-15T10:40:13.130
3271
43931
answer