ActiveRecord relation with nested objects to JSON - ruby

I'm using ActiveRecord with Sinatra. I have AR relation Post has_many Comments.
I need to create response in JSON that returns all posts and their comments. It should look like this:
[
{
"id":1,
"title:"Title_1",
"comments":[
{ "content":"lorem ipsum", "post_id":1 },
{ "content":"foo bar", "post_id":1 },
]
},
{
"id":2,
"title:"Title_2",
"comments":[
{ "content":"lorem ipsum", "post_id":2 },
{ "content":"foo bar", "post_id":2 },
]
}
]
I think it common task to create response like that, so I hope there should be some nice way to do it.
My temporary solution (the code below) works correctly but it too long and unreadable:
Post.all.map{|x| x.as_json(include: [:comments]).values[0] }.to_json
This is another solution that I found:
Post.all.as_json(include: [:comments]).to_json
Sadly, the returned structure looks different, it wraps every post into additional node "post: {}". I'd like to avoid it.
[
{
"post":{
"id":1,
"title:"Title_1",
"comments":[
{ "content":"lorem ipsum", "post_id":1 },
{ "content":"foo bar", "post_id":1 },
]
}
},
{
"post":{
"id":1,
"title:"Title_2",
"comments":[
{ "content":"lorem ipsum", "post_id":2 },
{ "content":"foo bar", "post_id":2 },
]
}
}
]

try:
ActiveRecord::Base.include_root_in_json = false
http://apidock.com/rails/ActiveRecord/Serialization/to_json

Related

Incorrectly selected data in the query

Only articles that contain the EmailMarketing tag are needed.
I'm probably doing the wrong search on the tag, since it's an array of values, not a single object, but I don't know how to do it right, I'm just learning graphql. Any help would be appreciated
query:
query {
enArticles {
title
previewText
tags(where: {name: "EmailMarketing"}){
name
}
}
}
result:
{
"data": {
"enArticles": [
{
"title": "title1",
"previewText": "previewText1",
"tags": [
{
"name": "EmailMarketing"
},
{
"name": "Personalization"
},
{
"name": "Advertising_campaign"
}
]
},
{
"title": "title2",
"previewText": "previewText2",
"tags": [
{
"name": "Marketing_strategy"
},
{
"name": "Marketing"
},
{
"name": "Marketing_campaign"
}
]
},
{
"title": "article 12",
"previewText": "article12",
"tags": []
}
]
}
}
I believe you first need to have coded an equality operator within your GraphQL schema. There's a good explanation of that here.
Once you add an equality operator - say, for example _eq - you can use it something like this:
query {
enArticles {
title
previewText
tags(where: {name: {_eq: "EmailMarketing"}}){
name
}
}
}
Specifically, you would need to create a filter and resolver.
The example here may help.

Spring Mongo - An aggregation to order by objects in an array

I have the following data:
{
"_id": ObjectID("5e2fa881c3a1a70006c5743c"),
"name": "Some name",
"policies": [
{
"cId": "dasefa-2738-4cf0-90e0d568",
"weight": 12
},
{
"cId": "c640ad67dasd0-92f981583568",
"weight": 50
}
]
}
I'm able to query this with Spring Mongo fine, however I want to be able to order the policies by weight
At the moment I get my results fine with:
return mongoTemplate.find(query, CArea::class.java)
However say I make the following aggregations:
val unwind = Aggregation.unwind("policies")
val sort = Aggregation.sort(Sort.Direction.DESC,"policies.weight")
How can I go and actually apply those to the returned results above? I was hoping that the dot annotation would do the job in my query however didnt do anything e.g. Query().with(Sort.by(options.sortDirection, "policies.weight"))
Any help appreciated.
Thanks.
I am not familier with Spring Mongo, but I guess you can convert the following aggregation to spring code.
db.collection.aggregate([
{
$unwind: "$policies"
},
{
$sort: {
"policies.weight": -1
}
},
{
$group: {
_id: "$_id",
"policies": {
"$push": "$policies"
},
parentFields: {
$first: "$$ROOT"
}
}
},
{
$replaceRoot: {
newRoot: {
$mergeObjects: [
"$parentFields",
{
policies: "$policies"
}
]
}
}
}
])
This will result:
[
{
"_id": "5e2fa881c3a1a70006c5743c",
"name": "Some name",
"policies": [
{
"cId": "c640ad67dasd0-92f981583568",
"weight": 50
},
{
"cId": "dasefa-2738-4cf0-90e0d568",
"weight": 12
}
]
}
]
Playground

Is it possible to get rid of the 'data' ,'nodes', ... fields?

I have the following GraphQL query:
{
allForums {
nodes {
name,
topics: topicsByForumId(orderBy: [TITLE_ASC]) {
nodes {
title
}
}
}
}
}
This returns something as following:
{
"data": {
"allForums": {
"nodes": [
{
"name": "1",
"topics": {
"nodes": [
{
"title": "a"
},
{
"title": "b"
}
]
}
}
]
}
}
}
I would like to get the result below:
[
{
"name": "1",
"topics": [
{
"title": "a"
},
{
"title", "b"
}
]
}
]
Is it possible to get rid of the data, nodes, ... fields? Is that something that can be done within GraphQL, or should I do that in my service implementation?
I am using PostGraphile v4.2.0 as a GraphQL implementation, on top of PostgreSQL v11.
As indicated in the docs, you can expose a simpler interface for connections, or eliminate the default Relay-based connection interface altogether:
If you prefer a simpler list interface over GraphQL connections then you can enable that either along-side our connections (both) or exclusively (only) using our --simple-collections [omit|both|only] option.

How to filter on a array with graphql in Generic Mesh CMS?

Im trying to get just entrys which have in a specific value in a array (myArray: [String]).
Displaying of this Array is not Problem:
query ($lang: [String!], $filter: String!) {
nodes(lang: $lang, filter: {schema: {is: myObj}, fields: {myObj: {name: {regex: $filter}}}}) {
elements {
uuid
language
availableLanguages
fields {
... on module {
name
myArray
}
}
node {
language
fields {
... on module {
name
myArray
}
}
}
}
}
}
Result:
{
"data": {
"nodes": {
"elements": [
{
"uuid": "xxxxxxxxxxxxxxxxxxxxxxxxxx",
"language": "de",
"availableLanguages": [
"de"
],
"fields": {
"name": "ASDF",
"myArray": [
"CAT_1",
"CAT_2"
]
},
"node": null
}
]
}
}
}
How can I filter on myArray? That I just et elements with the value uf $filter in the array myArray?
In the GraphiQL I can't find the myArray in the docs under the filter - fields.
GraphQL-Filtering for list types is not supported yet. In the GraphiQL docs you will only find supported fields for now.
See supported field types here: https://getmesh.io/docs/beta/graphql.html#_filtering_limitations
Here is the open issue on Github regarding this feature: https://github.com/gentics/mesh/issues/27

Querying array of nested objects

Say I have this JSON (sample - a real-life example can be found at apple itunes rss feed) stored in a RethinkDB table called 'test':
{
"feed": {
"entry": [
{
"title": {
"label": "Some super duper app"
},
"summary": {
"label": "Bla bla bla..."
}
},
{
"title": {
"label": "Another awsome app"
},
"summary": {
"label": "Lorem ipsum blabla..."
}
}
]
}
}
How would I write a ReQL query in JavaScript in order to fetch the summary of all entries (entry) which have title containing the string "xyz"? I expect the query result to return an array of matching entry objects, not an array of matching feed.
If I properly understood what you want to do, this query should be what you are looking for:
r.table("feeds").concatMap(function(doc) {
return doc("feed")("entry")
}).filter(function(entry) {
return entry("title")("label").match("xyz")
})

Resources