Я хочу показать сводку текста для модели в приложении Rails.Выберите простое значение в ActiveRecord
В настоящее время я делаю это так:
class ServiceOrder < ApplicationRecord
has_many :items, class_name: 'ServiceOrderItem',
dependent: :destroy,
inverse_of: :service_order
def link_text
items.left_outer_joins(:product)
.select("string_agg(coalesce(products.description, service_order_items.description), '; ') as description")
.group("service_order_items.service_order_id")
.map(&:description)
.first
end
end
class ServiceOrderItem < ApplicationRecord
belongs_to :service_order, inverse_of: :items
belongs_to :product, optional: true
end
class Product < ApplicationRecord
end
Что меня беспокоит то, что я пытаюсь выбрать одно значение, а не модель.
Этот запрос действительно возвращается "фальшивый" модель и извлечь значение, я хочу, но это своего рода Hacky:
- Добавить корректные отношения мне нужно
items.left_outer_joins(:product)
- Добавить значение выбора Я хочу
.select("string_agg(coalesce(products.description, service_order_items.description), '; ') as description")
- Добавить группу по п
.group("service_order_items.service_order_id")
- Выполнить запрос и извлечь описание "фальшивый" модель вернулась
.map(&:description)
- Я знаю, этот запрос возвращает только одно resu л, но он строит массив со всеми результатами, поэтому я извлечь один результат из массива
.first
Запрос Я хочу это:
select string_agg(coalesce(products.description, service_order_items.description), '; ')
from service_order_items
left outer join products on service_order_items.product_id = products.id
where service_order_items.service_order_id = :id
group by service_order_items.service_order_id;
И это запрос, который я генерирую, проблема в том, что результат заключен в объект модели, затем я преобразовываю его в массив, а затем извлекаю значение, которое я хочу.
Итак, как я могу указать активную запись, чтобы выбрать одно необработанное значение, а не список моделей?
Кстати, добавление .first
до .map
не работает, поскольку оно включает заказ в выполненном SQL, который у меня не может быть (order by service_order_items.id
).
Схема:
create_table "products", force: :cascade do |t|
t.integer "organization_id"
t.string "code"
t.string "description"
t.string "brand"
t.string "unit_of_measure"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.decimal "selling_price"
t.index ["organization_id"], name: "index_products_on_organization_id", using: :btree
end
create_table "service_order_items", force: :cascade do |t|
t.integer "service_order_id"
t.decimal "quantity"
t.string "description"
t.integer "product_id"
t.decimal "unit_price"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["product_id"], name: "index_service_order_items_on_product_id", using: :btree
t.index ["service_order_id"], name: "index_service_order_items_on_service_order_id", using: :btree
end
create_table "service_orders", force: :cascade do |t|
t.integer "organization_id"
t.text "description"
t.integer "state_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "customer_id"
t.integer "sequential_id"
t.date "start_date"
t.date "end_date"
t.index ["customer_id"], name: "index_service_orders_on_customer_id", using: :btree
t.index ["organization_id"], name: "index_service_orders_on_organization_id", using: :btree
t.index ["state_id"], name: "index_service_orders_on_state_id", using: :btree
end
Эй, Макс, ваше предложение действительно работало, но оно пропускает случай, когда элемент не имеет связанного с ним продукта. Я отредактировал вопрос, чтобы прояснить схему, а также обновил SQL для учета элементов без продуктов (это левое внешнее соединение с 'coalesce'). –
@ThiagoNegri Спасибо, я попытался обратиться к проблеме 'coalesce' с новыми изменениями. Это работает лучше? – Max
Он работал как шарм!Вы знаете, можно ли включить «условные включения»? Например, мне нужно включить продукты без описания. Я спрашиваю об этом, потому что сам «сервис-заказ» содержит поле «описание», поэтому «link_text» используется только тогда, когда у сервисного заказа нет описания, поэтому для этого конкретного заказа на обслуживание нет необходимости включать элементы и продукты. –