Несмотря на то, что ответ @ ray по большей части убедителен, я думаю, вам нужно будет добавить что-то дополнительное, чтобы получить заказанные размеры, как ожидалось, то есть «маленький, средний, большой».
В ответе Рэя это будет алфавитно, хотя я предполагаю, что вы хотите, чтобы оно было от маленького к большому или наоборот.
В результате ваш запрос будет выглядеть примерно так:
Product.joins(:category, :sizes).order("categories.title, title").order("CASE sizes.size_name WHEN 'SMALL' THEN 'a' WHEN 'MEDIUM' THEN 'b' WHEN 'LARGE' THEN 'c' ELSE 'z' END ASC")
Я добавил order
отдельно для оператора CASE
для удобства чтения, хотя вы также можете сделать что-то вроде:
Product.joins(:category, :sizes).order("categories.title, title, CASE sizes.size_name WHEN 'SMALL' THEN 'a' WHEN 'MEDIUM' THEN 'b' WHEN 'LARGE' THEN 'c' ELSE 'z' END ASC")
Лично я бы пошел на шаг дальше и сохранил бы размеры в виде столбца enum
в БД, если это вообще возможно:
enum size_name: [:small, :medium, :large]
# Or enum size_name: { small: 0, medium: 1, large: 2 }
Это делает код очень простым, поскольку в столбце enum хранится целое число в порядке, указанном выше:
Product.joins(:category, :sizes).order("categories.title, title, sizes.size_name")
Наконец, у этого есть бонусные очки: у вас будет доступ к таким методам, как Size.medium
, size.medium?
, size.large!
и так далее:)
Надеюсь, это поможет - дайте мне знать, если у вас есть какие-либо вопросы или комментарии!
Редактировать на основе обновления вопроса
Чтобы начать с Size
, вам нужно настроить одно из следующих:
Size.joins(product: :category).order("CASE sizes.size_name WHEN 'SMALL' THEN 'a' WHEN 'MEDIUM' THEN 'b' WHEN 'LARGE' THEN 'c' ELSE 'z' END ASC").order("categories.title, products.title")
или с enum
:
Size.joins(product: :category).order("sizes.size_name, categories.title, products.title")