GORMのScopesとOrderを使って並び替えします。
フロントはReactでGoのフレームワークechoを使ってます。
ECサイトのトップページで新着順、価格が高い順、低い順に並び替えるようなイメージです。
React
CustomerTop.js
import React from 'react';
import Button from '@material-ui/core/Button';
class CustmerTop extends React.Component {
constructor(props) {
super(props);
this.state = {
products: [],
};
}
componentDidMount() {
this.getCustomerProduct();
}
getCustomerProduct(order) {
return http
.get(`/customer/products?order=${order}`)
.then(response => {
this.setState({ products: response.data });
})
.catch(function (error) {
console.log(error);
});
}
render() {
return (
<div className="slide-menu">
<Button
className="slide-menu__item-order"
onClick={() => this.getCustomerProducts('latest')}
>
新着順
</Button>
<Button
className="slide-menu__item-order"
onClick={() => this.getCustomerProducts('low')}
>
価格低い順
</Button>
<Button
className="slide-menu__item-order"
onClick={() => this.getCustomerProducts('high')}
>
価格高い順
</Button>
</div>
);
}
}
export default CustmerTop;
記述だいぶ省いていますが、${order}を可変にしてそこに'latest'だったり、'low'という文字列が入ってくるようにします。そしてGo側に投げます。
Go
product.go
func (h *handler) getCustomerProducts(c echo.Context) error {
var products []models.Product
order := c.QueryParam("order")
err = h.DB.
Where("public=true").
Scopes(func(ddb *gorm.DB) *gorm.DB {
if order == "latest" {
return ddb.Order("products.created_at DESC")
}
if order == "low" {
return ddb.Order("price ASC")
}
if order == "high" {
return ddb.Order("price DESC")
}
return ddb
}).
Find(&products).Error
if err != nil {
return err
}
return c.JSON(http.StatusOK, products)
}
echoのQueryParamでパラメーターを見て、公開されている商品をorderに入ってきた文字列に対応するように並び替えることができます。
他にも在庫の有無で絞ったり、商品が属するカテゴリーで検索するときにもScopesが使えてとても便利です。
以上です。