How to serialze the correct fields that are stored on has a has_many through relation table - ruby-on-rails-5

I have a has_many through relationship. But I need to serialize a field stored on the relation table as workflow_state.
To do this I have to access the relation table directly.
Here is the current serializer I have:
class OrderSerializer < ActiveModel::Serializer
attributes :id, :number, :slug, :quoted, :invoiced, :paid, :reciepted, :void, :refund, :workflow_state
has_one :table
has_one :user
has_one :quote
has_one :reciept
has_many :items
class RecieptSerializer < ActiveModel::Serializer
attributes :id, :order_number, :number, :slug, :cost, :paid, :vat, :total, :change
end
class UserSerializer < ActiveModel::Serializer
attributes :id, :name, :email
end
class QuoteSerializer < ActiveModel::Serializer
attributes :id, :order_number, :number, :slug, :cost, :vat, :total
end
class TableSerializer < ActiveModel::Serializer
attributes :id, :number, :position
end
def items
customized_items = []
object.items.each do |item|
# Assign object attributes (returns a hash)
# ===========================================================
custom_item = item.attributes
# has_one w/only specified attributes
custom_item[:category] = item.category.slice(:id, :name, :icon)
custom_item[:workflow_state] = item.order_items.find_by_item_id(item.id).workflow_state
customized_items.push(custom_item)
end
return customized_items
end
end
The issue is it gives the correct type of response however the field it shows is wrong says 'created' for all items. But when I check the database, the field is "preparing".
Response:
{
"order": {
"id": 7,
"number": 7,
"slug": "61b8a5ad-b3f9-4492-b7d7-2c61684c4988",
"quoted": true,
"invoiced": false,
"paid": false,
"reciepted": false,
"void": false,
"refund": false,
"workflow_state": "preparing",
"table": {
"id": 9,
"number": 9,
"position": "Bar"
},
"user": {
"id": 1,
"name": "admin",
"email": "admin#admin.com"
},
"quote": {
"id": 7,
"order_number": 7,
"number": 7,
"slug": "43f0ca98-84dc-4e6d-8062-f3f1ef1f2e5f",
"cost": "22.0",
"vat": "0.0",
"total": "22.0"
},
"reciept": null,
"items": [
{
"id": 1,
"name": "Eggs bendict",
"icon": "breakfast",
"cost": "5.5",
"price": "7.5",
"description": "Eggs on toasted muffins with holindais sauce",
"category_id": 1,
"organisation_id": 1,
"created_at": "2020-06-26T07:45:44.603Z",
"updated_at": "2020-06-26T07:45:44.603Z",
"category": {
"id": 1,
"name": "Breakfast",
"icon": "breakfast"
},
"workflow_state": "created"
},
{
"id": 1,
"name": "Eggs bendict",
"icon": "breakfast",
"cost": "5.5",
"price": "7.5",
"description": "Eggs on toasted muffins with holindais sauce",
"category_id": 1,
"organisation_id": 1,
"created_at": "2020-06-26T07:45:44.603Z",
"updated_at": "2020-06-26T07:45:44.603Z",
"category": {
"id": 1,
"name": "Breakfast",
"icon": "breakfast"
},
"workflow_state": "created"
},
{
"id": 1,
"name": "Eggs bendict",
"icon": "breakfast",
"cost": "5.5",
"price": "7.5",
"description": "Eggs on toasted muffins with holindais sauce",
"category_id": 1,
"organisation_id": 1,
"created_at": "2020-06-26T07:45:44.603Z",
"updated_at": "2020-06-26T07:45:44.603Z",
"category": {
"id": 1,
"name": "Breakfast",
"icon": "breakfast"
},
"workflow_state": "created"
},
{
"id": 13,
"name": "Fries",
"icon": "fries",
"cost": "5.5",
"price": "7.5",
"description": "Fries",
"category_id": 5,
"organisation_id": 1,
"created_at": "2020-06-26T07:45:44.636Z",
"updated_at": "2020-06-26T07:45:44.636Z",
"category": {
"id": 5,
"name": "Sides",
"icon": "fries"
},
"workflow_state": "created"
}
]
}
}
What I'm thinking is this:
custom_item[:workflow_state] = item.order_items.find_by_item_id(item.id).workflow_state
Its probably serializing the first item that in order_items with item id as specified.
Is there a better way to serialise a field from the relation table for a given relation?

I refactored the whole app to not use a has_many :through relationship.

Related

Get specific value from json field based on last created_at date

I am using retool, which uses AlaSQL to query JSON, trying to get the value from a field that has multiple items; I only want to return the value of the field stock for the key with the latest created_at date.
select tracked_products
from {{ean.data}}
where created_at=(select MAX(created_at) from {{ean.data}});
I can actually get to the fields I want to like this but I do not understand how to filter further
select tracked_products
from {{ean.data}}
where price < 40
result from above query in plain text
[
{
"id": 172165913,
"offer_data_id": 2208536,
"stock": 2,
"sold": 0,
"revenue": "0.00",
"price": 39.99,
"status": "success",
"created_at": "2022-12-16T12:12:26.000000Z",
"updated_at": "2022-12-16T12:12:26.000000Z"
},
{
"id": 173409443,
"offer_data_id": 2208536,
"stock": 2,
"sold": 0,
"revenue": "0.00",
"price": 34.99,
"status": "success",
"created_at": "2022-12-17T03:15:58.000000Z",
"updated_at": "2022-12-17T03:15:58.000000Z"
},
{
"id": 174659591,
"offer_data_id": 2208536,
"stock": 2,
"sold": 0,
"revenue": "0.00",
"price": 34.99,
"status": "success",
"created_at": "2022-12-18T16:22:45.000000Z",
"updated_at": "2022-12-18T16:22:45.000000Z"
},
{
"id": 175895075,
"offer_data_id": 2208536,
"stock": 2,
"sold": 0,
"revenue": "0.00",
"price": 34.99,
"status": "success",
"created_at": "2022-12-19T03:18:53.000000Z",
"updated_at": "2022-12-19T03:18:53.000000Z"
},
{
"id": 177134025,
"offer_data_id": 2208536,
"stock": 2,
"sold": 0,
"revenue": "0.00",
"price": 34.99,
"status": "success",
"created_at": "2022-12-20T15:35:48.000000Z",
"updated_at": "2022-12-20T15:35:48.000000Z"
},
{
"id": 178391290,
"offer_data_id": 2208536,
"stock": 2,
"sold": 0,
"revenue": "0.00",
"price": 34.99,
"status": "success",
"created_at": "2022-12-21T03:09:22.000000Z",
"updated_at": "2022-12-21T03:09:22.000000Z"
},
{
"id": 179654380,
"offer_data_id": 2208536,
"stock": 1,
"sold": 1,
"revenue": "34.99",
"price": 34.99,
"status": "success",
"created_at": "2022-12-22T03:13:50.000000Z",
"updated_at": "2022-12-22T03:13:50.000000Z"
},
{
"id": 180918092,
"offer_data_id": 2208536,
"stock": 1,
"sold": 0,
"revenue": "0.00",
"price": 34.99,
"status": "success",
"created_at": "2022-12-23T03:19:42.000000Z",
"updated_at": "2022-12-23T03:19:42.000000Z"
}
]
try this :
SELECT DISTINCT
(array_agg(j->>'stock') OVER (PARTITION BY tracked_products ORDER BY j->>'created_at' DESC)[1] AS stock
FROM ean.data
CROSS JOIN LATERAL jsonb_path_query(tracked_products :: jsonb, '$[*]') AS j
WHERE price < 40
This query relies on a text sorting on created_at which should be compliant with the actual date format of this text field.
jsonb_path_query is used instead of json_array_elements so that to avoid an error when tracked_products is not a json of type array.
see dbfiddle
Refer to the manual for more info about json manipulation

TypeORM innerJoin table and filter by joined table

This is my actual query:
const query = this.doctorsRepository.createQueryBuilder('doctor')
.innerJoinAndSelect('doctor.services', 'services')
await query.getMany();
This is the result:
[
{
"id": 3,
"created_at": "2021-09-09T14:11:09.779Z",
"updated_at": "2021-09-09T14:11:09.779Z",
"name": "Test Doctor Name",
"bio": "Test Doctor Bio",
"services": [
{
"id": 1,
"created_at": "2021-08-18T17:35:52.506Z",
"updated_at": "2021-08-18T17:35:52.506Z",
"title": "new service by me"
},
{
"id": 2,
"created_at": "2021-08-13T15:58:01.918Z",
"updated_at": "2021-08-13T15:58:01.918Z",
"title": "testing service creation at night again & again"
}
]
},
{
"id": 2,
"created_at": "2021-09-09T12:58:05.564Z",
"updated_at": "2021-09-09T13:47:37.299Z",
"name": "Doctor Name",
"bio": "Doctor Bio",
"services": [
{
"id": 26,
"created_at": "2021-08-13T08:47:07.941Z",
"updated_at": "2021-08-13T08:47:07.941Z",
"title": "service 26"
},
{
"id": 36,
"created_at": "2021-08-13T08:49:22.732Z",
"updated_at": "2021-08-13T08:49:22.732Z",
"title": "service 36"
},
{
"id": 1,
"created_at": "2021-08-08T19:18:26.056Z",
"updated_at": "2021-08-08T19:18:26.056Z",
"title": "service 1"
},
{
"id": 77,
"created_at": "2021-08-13T10:12:55.529Z",
"updated_at": "2021-08-13T10:12:55.529Z",
"title": "testy 10"
}
]
}]
As you see, I have Doctor & Service entity that Doctor entity has Many-to-Many relation with service entity. Everything is ok until here.
But I wanna filter result by services ids, I mean I have an array of ids like this:
const servicesArray = [1, 2]
And I wanna filter result by services ids. I tested many ways but I didn't get my answer.
Note: This code didn't solve my problem:
andWhere('services.id in (:...ids)', {
ids: servicesArray,
})
And for better understanding this is what I expect:
Items that filtered by services ids (item that has services with the id of 1 and 2);
[
{
"id": 3,
"created_at": "2021-09-09T14:11:09.779Z",
"updated_at": "2021-09-09T14:11:09.779Z",
"name": "Test Doctor Name",
"bio": "Test Doctor Bio",
"services": [
{
"id": 1,
"created_at": "2021-08-18T17:35:52.506Z",
"updated_at": "2021-08-18T17:35:52.506Z",
"title": "new service by me"
},
{
"id": 2,
"created_at": "2021-08-13T15:58:01.918Z",
"updated_at": "2021-08-13T15:58:01.918Z",
"title": "testing service creation at night again & again"
}
]
},
]
I also added :
query
.addSelect('COUNT(services.id)', 'services_count')
.groupBy('services.id')
.addGroupBy('doctor.id');
But the problem isn't solved, because addSelect doesn't work with getMany, it works with getRawMany.

Podio Api: Why does PUT request /app/{app_id}/field/{field_id} delete category field options for contact apps?

I'm tring to modify category fields of a contact app using Podio API.
I get the following response for the GET request (https://api.podio.com/app/22768616/field/189304190):
(Previously I created the field with a POST request and everything works fine)
{
"status": "active",
"type": "category",
"field_id": 189304190,
"label": "myCategories",
"config": {
"default_value": null,
"unique": false,
"description": null,
"hidden_create_view_edit": false,
"required": false,
"mapping": null,
"label": "myCategories",
"visible": true,
"delta": 9,
"hidden": false,
"settings": {
"multiple": false,
"options": [
{
"status": "active",
"text": "Cat1",
"id": 1,
"color": "DCEBD8"
},
{
"status": "active",
"text": "Cat2",
"id": 2,
"color": "DCEBD8"
},
{
"status": "active",
"text": "Cat3",
"id": 3,
"color": "DCEBD8"
},
{
"status": "active",
"text": "Cat4",
"id": 4,
"color": "DCEBD8"
}
],
"display": "dropdown"
}
},
"external_id": "mycategories-2"
}
If I send a PUT request to https://api.podio.com/app/22768616/field/189304190 with the same response, the dropdown category field changes to an inline category field and all the options are deleted. (I expected nothing would happen to my field, I also tried to modify the text of the options, but got the same result).
{
"status": "active",
"type": "category",
"field_id": 189304190,
"label": "myCategories",
"config": {
"default_value": null,
"unique": false,
"description": null,
"hidden_create_view_edit": false,
"required": false,
"mapping": null,
"label": "myCategories",
"visible": true,
"delta": 0,
"hidden": false,
"settings": {
"multiple": false,
"options": [
{
"status": "deleted",
"text": "Cat1",
"id": 1,
"color": "DCEBD8"
},
{
"status": "deleted",
"text": "Cat2",
"id": 2,
"color": "DCEBD8"
},
{
"status": "deleted",
"text": "Cat3",
"id": 3,
"color": "DCEBD8"
},
{
"status": "deleted",
"text": "Cat4",
"id": 4,
"color": "DCEBD8"
}
],
"display": "inline"
}
},
"external_id": "mycategories-2"
}
Could you please help with any example to update a category fields correctly?
Can you add what the body is when you are using the PUT endpoint?
My guess is that you are somehow not mapping the "settings" parameter correctly. Per the API documentation the settings parameter for a category field should follow this format:
{
"options": The list of options for the question
[
{
"id": The id of the option, only use this for existing options,
"status": The current status of the option, "active" or "deleted", only use this to delete options,
"text": The text for the option (required)
},
... (more options)
],
"multiple": True if multiple answers should be allowed, False otherwise
}

Add Product Variant - 404 Error

I am developing a VB.NET application to interact with our new Shopify store. I am in the process of automating product additions/updates/removal based on data in our Oracle database.
Basically the application creates a new Shopify part for a pattern, then creates product variants for each sku in that pattern. It does this by POSTing and PUTing requests using the HttpWebRequest class. This was working great through yesterday afternoon, now today for some reason it's failing on the product variant creation/update with a 404 - Not Found error code.
The product add request JSON is below. This works perfectly, it creates the part on Shopify which I can then see through the admin panel. This is POSTed to the URL "https://key:password#bath-and-window-direct.myshopify.com/admin/products.json" (where key and password are replaced with our credentials)
{
"product": {
"id": 0,
"body_html": "A classic combination of embroidery and cut work form the flowing border, creating your own seaside retreat. ",
"title": "Seabreeze Sand",
"vendor": "SKL",
"product_type": "",
"published_scope": "global",
"tags": "J71227",
"variants": null,
"options": null,
"images": [{
"id": 0,
"product_id": 0,
"position": 1,
"src": "http:\/\/i320.photobucket.com\/albums\/nn353\/fkhphoto\/J71227main.jpg",
"variant_ids": null
}],
"image": null
}
}
This is the JSON reply I'm receiving after this call, and I can also see the part added in the Shopify admin panel:
{
"product": {
"id": 7874734983,
"title": "Seabreeze Sand",
"body_html": "A classic combination of embroidery and cut work form the flowing border, creating your own seaside retreat. ",
"vendor": "SKL",
"product_type": "",
"created_at": "2016-07-14T10:43:56-04:00",
"handle": "seabreeze-sand",
"updated_at": "2016-07-14T10:43:56-04:00",
"published_at": "2016-07-14T10:43:56-04:00",
"template_suffix": null,
"published_scope": "global",
"tags": "J71227",
"variants": [{
"id": 24925005383,
"product_id": 7874734983,
"title": "Default Title",
"price": "0.00",
"sku": "",
"position": 1,
"grams": 0,
"inventory_policy": "deny",
"compare_at_price": null,
"fulfillment_service": "manual",
"inventory_management": null,
"option1": "Default Title",
"option2": null,
"option3": null,
"created_at": "2016-07-14T10:43:56-04:00",
"updated_at": "2016-07-14T10:43:56-04:00",
"taxable": true,
"barcode": null,
"image_id": null,
"inventory_quantity": 1,
"weight": 0.0,
"weight_unit": "lb",
"old_inventory_quantity": 1,
"requires_shipping": true
}],
"options": [{
"id": 9404426823,
"product_id": 7874734983,
"name": "Title",
"position": 1,
"values": ["Default Title"]
}],
"images": [{
"id": 16242879303,
"product_id": 7874734983,
"position": 1,
"created_at": "2016-07-14T10:43:56-04:00",
"updated_at": "2016-07-14T10:43:56-04:00",
"src": "https://cdn.shopify.com/s/files/1/1363/2407/products/J71227main.jpg?v=1468507436",
"variant_ids": []
}],
"image": {
"id": 16242879303,
"product_id": 7874734983,
"position": 1,
"created_at": "2016-07-14T10:43:56-04:00",
"updated_at": "2016-07-14T10:43:56-04:00",
"src": "https://cdn.shopify.com/s/files/1/1363/2407/products/J71227main.jpg?v=1468507436",
"variant_ids": []
}
}
}
Immediately after that, I'm POSTing the following JSON to add a product variant to this newly created part, to the URL "https://key:password#bath-and-window-direct.myshopify.com/admin/products/7874734983/variants.json". This is the call that returns a 404 - Not Found error through the HttpWebRequest class.
{
"variant": {
"id": 0,
"product_id": 7874734983,
"title": "Seabreeze Tier Curtain in Sand",
"price": "11.99",
"sku": "J7122700013V09",
"compare_at_price": "0.00",
"position": 0,
"grams": 0,
"option1": "57X13 ROD POCKET VAL",
"option2": null,
"option3": null,
"taxable": true,
"barcode": "036326422417",
"weight": 0,
"weight_unit": "lb",
"inventory_quantity": 550,
"old_inventory_quantity": 550,
"requires_shipping": true,
"image_id": null,
"metafields": [{
"id": 0,
"key": "point1",
"value": "57 x 13 Valance",
"value_type": "string",
"namespace": "J7122700013V09"
},
{
"id": 0,
"key": "point2",
"value": "To achieve the look in the photo, use one valance and one tier pair.",
"value_type": "string",
"namespace": "J7122700013V09"
},
{
"id": 0,
"key": "point3",
"value": "Feels like you are in your own beach cottage.",
"value_type": "string",
"namespace": "J7122700013V09"
},
{
"id": 0,
"key": "point4",
"value": "100% Polyester.",
"value_type": "string",
"namespace": "J7122700013V09"
},
{
"id": 0,
"key": "point5",
"value": " ",
"value_type": "string",
"namespace": "J7122700013V09"
}]
}
}
What am I doing wrong? The URLs, when copied into a web browser, work perfectly fine...I can see all the JSON of the current data. But when attempting to add the variant, I'm getting the 404.
Try leaving out the "id": 0 properties — both from the variant and from the metafields. Shopify will determine the IDs automatically.

Stock Quantity of ProductVariant not decreased in shopify shop when placing order via API

I am posting the following Order to the shopify api Order endpoint. The Order shows up in the shop and everything works as it should, except that the stock quantity of the variants in orders placed via the API are not decreased automatically by shopify. When I place an order within the admin console, they are decreased automatically. Shopify inventory tracking is turned on for the products. Any ideas would be greatly appreciated.
{
"order": {
"email": "someName#yahoo.com",
"financial_status": "paid",
"fulfillment_status": null,
"send_receipt": true,
"send_fulfillment_receipt": true,
"note": "Created by someName",
"line_items": [
{
"variant_id": 21718275463,
"quantity": 1,
"price": 99,
"requires_shipping": true,
"product_id": 6820646151
},
{
"variant_id": 21717700871,
"quantity": 1,
"price": 1000,
"requires_shipping": true,
"product_id": 6820646151
},
{
"variant_id": 21717690055,
"quantity": 1,
"price": 555,
"requires_shipping": true,
"product_id": 6821668807
}
],
"processing_method": "offsite",
"shipping_address": {
"first_name": "Chris",
"address1": "111 Love Road",
"phone": "9999999999",
"city": "St. Louis",
"zip": "63123",
"province": "MO",
"country": "United States",
"last_name": "Becker",
"name": "Chris Becker",
"country_code": "US",
"province_code": "MO"
},
"source_name": "someName",
"taxes_included": false,
"shipping_lines": [
{
"title": "standard",
"price": 0.00,
"code": null,
"source": "brand owner on shopify",
"carrier_identifier": null,
"tax_lines": null
}
],
"tags": "someName"
}
}
{
"variant": {
"id": 21718275463,
"product_id": 6820646151,
"title": "m / red",
"price": "99.00",
"sku": "",
"position": 2,
"grams": 0,
"inventory_policy": "deny",
"compare_at_price": "900.00",
"fulfillment_service": "manual",
"inventory_management": "shopify",
"option1": "m",
"option2": "red",
"option3": null,
"created_at": "2016-05-27T13:16:26-04:00",
"updated_at": "2016-05-28T13:28:20-04:00",
"taxable": false,
"barcode": "",
"image_id": 13217378823,
"inventory_quantity": 1,
"weight": 0,
"weight_unit": "lb",
"old_inventory_quantity": 1,
"requires_shipping": true
}
}
{
"variant": {
"id": 21717700871,
"product_id": 6820646151,
"title": "s / green",
"price": "1000.00",
"sku": "",
"position": 1,
"grams": 0,
"inventory_policy": "deny",
"compare_at_price": "1111.00",
"fulfillment_service": "manual",
"inventory_management": "shopify",
"option1": "s",
"option2": "green",
"option3": null,
"created_at": "2016-05-27T13:05:56-04:00",
"updated_at": "2016-05-28T12:17:22-04:00",
"taxable": true,
"barcode": "",
"image_id": 13160712135,
"inventory_quantity": 2,
"weight": 0,
"weight_unit": "lb",
"old_inventory_quantity": 2,
"requires_shipping": true
}
}
{
"variant": {
"id": 21717690055,
"product_id": 6821668807,
"title": "Default Title",
"price": "555.00",
"sku": "",
"position": 1,
"grams": 0,
"inventory_policy": "deny",
"compare_at_price": "666.00",
"fulfillment_service": "manual",
"inventory_management": "shopify",
"option1": "Default Title",
"option2": null,
"option3": null,
"created_at": "2016-05-27T13:05:39-04:00",
"updated_at": "2016-05-28T12:17:22-04:00",
"taxable": true,
"barcode": "",
"image_id": null,
"inventory_quantity": 2,
"weight": 0,
"weight_unit": "lb",
"old_inventory_quantity": 2,
"requires_shipping": true
}
}
You created a fake order using the API. Fake orders like that don't transact money or trigger the usual internal checks and balances without some extra effort. Maybe if you tried adding a fulfillment to the order, Shopify might ding inventory levels? Seems like something to try anyway.