цепочка и заказ от разных моделей - PullRequest
0 голосов
/ 10 января 2019

у меня 3 модели

  • Размер , что belongs_to: :product
  • Продукт , has_many: :sizes и belongs_to: :category
  • Категория , что has_many: :products

Я хочу отсортировать их в таблице в моем индексе товаров по названию категории, затем по названию продукта, затем по размеру

Caegories | Product | Size |
----------------------------
   A      |   A     | S    |
   A      |   A     | M    |
   A      |   B     | S    |
   A      |   C     | S    |
   B      |   A     | S    |
   B      |   A     | M    |
   B      |   B     | S    |
   B      |   C     | S    |

Как я должен связать и заказать все это? это возможно?

обновление

create_table "categories", force: :cascade do |t|
    t.string "title", limit: 100, null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end


create_table "products", force: :cascade do |t|
    t.string "title", limit: 150, null: false
    t.decimal "price", precision: 15, scale: 2, default: "0.0", null: false
    t.text "description"
    t.bigint "category_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "color"
    t.integer "user_id"
    t.json "attachments"
    t.index ["category_id"], name: "index_products_on_category_id"
  end

  create_table "sizes", force: :cascade do |t|
    t.string "size_name"
    t.integer "quantity"
    t.bigint "product_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["product_id"], name: "index_sizes_on_product_id"
  end

Я думаю, что я бы предпочел начать заказ по размеру, чтобы отобразить каждый размер ... Но я не знаю, как ...

index.html.erb

<% "my query???".each do |size| %>
    <td><%= size.product.category.title %></td>
    <td><%= size.product.title %></td>
    <td><%= size.product.price %></td>
    <td><%= size.size_name %></td>
    <td><%= size.quantity %></td>
<% end %>

Ответы [ 2 ]

0 голосов
/ 10 января 2019

Несмотря на то, что ответ @ 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")
0 голосов
/ 10 января 2019

Я не проверял следующее, но должен работать,

Я не получил вашу схему таблицы sizes правильно. Предполагая, что Size модель имеет столбец type для хранения таких значений, как L (большой), S (маленький) и M (средний).

Product.joins(:category, :sizes).order('categories.title, title, sizes.type')

Убедитесь, что ваши ассоциации и схемы таблиц правильные

Примечание: AS для вашей обновленной схемы,

Product.joins(:category, :sizes).order('categories.title, title, sizes.size_name')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...