Retrieving many-to-many results from GORM - mysql

I am mapping my database using gorm.
I have two tables (service and resource) with a many-to-many relationship. I am modelling them in code as such:
type Service struct {
BaseModel
Name string `gorm:"not null;unique_index"`
Resources []Resource `gorm:"many2many:service_resource"`
}
type Resource struct {
BaseModel
Name string `gorm:"not null;unique_index"`
}
Using gorm's AutoMigrate the following tables are created:
(I also executed a raw SQL query to add the id primary key in the mapping table.)
To create a new service, I use the following code:
service := Service{
Name: "core",
Resources: []Resource{
{Name: "ec2"},
{Name: "dynamo"},
},
}
db.Create(&service)
This creates all the resources along with the service and fills in the relationship between them in the service_resource table just fine, as expected.
However, my problem is when I'm querying for the services. I use the following code to retrieve all services:
services := []model.Service{}
db.Find(&services)
This returns successfully with the services array populated, but the Resources array of each service is empty:
"services": [
{
"ID": 1,
"Name": "core",
"Resources": null
},
...
]
I was under the assumption that gorm would populate it automatically. Is there some step that I'm missing?

You need to Preload the resources field before querying for services:
services := []model.Service{}
db.Preload("Resources").Find(&services) // error checking ommited
This correctly populates the Resources field of every service.

Related

How to create public Forge Design Automation Activity and Package?

I would like to create a public Design Automation Activity and Package so other Forge apps with unknown ClientId & Secret can use our corporate DA tools. So I am setting the isPublic: true flag on the payload but, to my great despair, isn't working.
Take a look at my POST activity payload below:
const activityParams = {
id: DA_ACTIVITY_ID,
commandLine: [
`$(engine.path)\\accoreconsole.exe ` +
`/i \"$(args[inputDwg].path)\" ` +
`/al \"$(appbundles[${DA_APP_BUNDLE_ID}].path)\" ` +
`/s \"$(settings[script].path)\"`
],
parameters: {
inputDwg: {
description: "input .dwg",
localName: "input.dwg",
ondemand: false,
required: true,
verb: "get",
zip: false
},
result: {
description: "result .json",
localName: "result.json",
ondemand: false,
required: false,
verb: "put",
zip: false
}
},
settings: {
script: "(command \"EXTRACTGEOBIMDATA\")\n"
},
description: "GeoBIM Extract Data",
engine: DA_ENGINE,
appbundles: [
fullAppBundleId
],
isPublic: true
}
The first thing I notice is that the response after successful creation of activity doesn't contain the isPublic field:
The second thing I'm forced to notice is that attempting to execute a workitem against that activity result in an error:
Note that when run with the same credentials the activity and workitem are running perfectly fine.
Design Automation V3 let you use individual alias to share an Activity or AppBundle with a specific forge app.
If you look at the documentation when creating an alias for activity and AppBundle, there is an optional parameter you can set in the request body named "receiver". You can specify a forge app client id or nickname if the forge app you want to share with have one setup in Design Automation.
Note that if the Forge app you want to set as receiver use a nickname, you must use that nickname instead of the app client id.
https://forge.autodesk.com/en/docs/design-automation/v3/reference/http/activities-id-aliases-POST/
https://forge.autodesk.com/en/docs/design-automation/v3/reference/http/appbundles-id-aliases-POST/
We don't currently allow people to create public activities. This is because it is not clear how the parties could establish a trust relationship necessary. It sounds like in your scenario the sharing would happen within the same org. Would they have the same email domain (eg. xyz#somecompany.com would share with bla#somecompany.com)?

Correct implementation of MySQL tables in MongoDB?

I'm new to mongoDB, and I wonder how I can translate tables relations in MongoDB.
For example in my MySQL base, I have two tables : Manager and Employee.
Manager {
name: String,
ID: Int Primary Key
}
Employee {
name: String,
ID: Int Primary Key,
Manager: int Foreign key (Manager.ID)
}
I would like to know what is the correct way to implement this with MongoDB.
MongoDB is a non-relational document database.
'Document' is a record in a collection and each document can have any number of fields, including arrays, maps, etc. The strength and weakness of this are that two documents in the same collection may hold completely different fields. Normal forms of relational databases do not apply. Also, each document has a unique id.
How to link documents/collections together is completely up to the app logic.
Few options:
Keep everything together in once collection.
//
{
name: "Jon Appleseed",
manager: "Jonh Bosch"
},
{
name:"Another employee",
manager: "Jonh Bosch"
}
Use two collections as suggested by #iprakashv
Use a mixed approach:
// Employees
{
_id: "_234234",
name: "Jon Appleseed",
manager:{
name:"John Bosh",
id: _12321
}
},
{
_id: "_233234",
name: "Another employee",
manager:{
name:"John Bosh",
id: "_12321"
}
}
// Managers
{
_id: _123213,
name:"John Bosh",
subordinates:
[
{name:"Jon Appleseed", id: "_234234" },
{name:"Another employee", id: "_12321" },
]
}
As you see, you gain much more flexibility at the expense of normalization.
As mongodb is a NoSQL database for schema-less and relation-less collections (though you can put validations over a collection), join-less schema and nested objects make more sense here.
Now as per our requirement, each Manager object is linked to its employee so, should ideally have an array containing all its employee objects, but, it is not practical when we need all the employees irrespective of the Manager.
So, we may want to have just the array of employee id's instead of an array of employee objects and employee collection (table) to be maintained separately to fetch employee objects.
The samples documents for the above schema would look like:
//employee collection document
{
"ID": "E12334",
"name": "John Doe"
}
//manager collection document
{
"ID": "M453",
"name": "Jane Doe",
"employeeIDs": ["E12334", "E12343"]
}

Creating a connection type in AWS AppSync to retrieve data from Aurora Serverless

so I have a Aurora Serverless DB in Amazon RDS. I would like to use this within GraphQL and set up connections between certain types. I.e, a User could have a list of Followers and that's used with a UserFollowerConnection type. What I would like this to do is paginate and only retrieve maybe 10 items at a time, and keep track of the nextToken. I was able to do this successfully with DynamoDB tables but I am trying to replicate the same implementation with RDS.
My schema looks something like this:
type User {
userId: String!
userName: String!
fullName: String!
displayName: String!
email: String!
followers(limit: Int, nextToken: String): UserFollowerConnection
}
type UserFollower {
userId: String!
followerId: String!
dateFollowed: AWSDateTime!
}
type UserFollowerConnection {
items: [UserFollower]
nextToken: String
}
My current resolver implementation for DynamoDB looks something like this:
{
"version" : "2017-02-28",
"operation" : "Query",
"query" : {
## Provide a query expression. **
"expression": "userId = :id",
"expressionValues" : {
":id": {
"S": "$ctx.source.userId"
}
}
},
"limit": #if($context.arguments.limit) $context.arguments.limit #else 10 #end,
"nextToken": #if($context.arguments.nextToken) "$context.arguments.nextToken" #else null #end
}
What would be the best practice for implementing this for AuroraServerless/MySQL? Would I write this code within the resolver on AppSync as shown in the documentation, or should this be a Lambda function that is connected to the resolver?
i hope you fixed your problem.
I`m currently in the same situation.
And there's another obstacle when trying to implement this functionality with mysql: Pagination
https://github.com/aws-amplify/amplify-cli/issues/3111
Would be great if you could post your resolver once you have fixed the problem.

How to create AWS ECS cluster via AWS Cloudformation only if it DOES NOT exists

I am specifying following block of code in my .json to create a cluster via AWS cloudformation.
"MyCluster": {
"Type" : "AWS::ECS::Cluster",
"Properties" : {
"ClusterName" : {
"Ref": "EcsCluster"
}
}
}
I would like to provision a exception condition to ignore cluster creation if cluster with a particular name already exists.
Any help would be highly appreciated.
You can only conditionally create resources based on Conditions values, and all conditions are evaluated at 'start time' of the template, and based only on simple string and logical operations on your input parameters. So you can't do anything like use a custom resource to check if the cluster already exists and skip creating it if so.
You could use a Custom Resource to munge the name of the ECS Cluster the stack creates, checking if your preferred name is already 'taken' and returning a different, non-conflicting name if so.
If you need to eliminate the resource completely, you either need to add a parameter to turn it on or off:
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
CreateCluster:
Type: "String"
Description: "Whether to create the ECS Cluster"
AllowedValues: [ "true", "false" ]
Default: "false"
...
Conditions:
CreateCluster: { "Fn::Equals": [ { Ref: "CreateCluster" }, "true" ] }
....
Resources:
MyCluster:
Type: "AWS::ECS::Cluster"
Properties:
ClusterName: { Ref: "EcsCluster" }
Condition: "CreateCluster"
Or you need to use a Transform to rewrite the template, check whether the cluster exists, and remove the resource definition if so.

Laravel - Mysql to JSON

At the moment I have a list of employees as a json file.
{
"id": 1,
"departments": "1",
"name": "Bill Smith",
"profilePic": "/img/people/Office/bill-smith.jpg",
"title": "Office Manager"
},
I now want to store these in the database but still return them as JSON.
How do I set this up with my routes? It will be a very basic filter, by department id.
I presume I would do a get request
Route::get('people/{department}', function () {
});
How do I return the json?
If you have an Employee model, it would look like this:
Route::get('people/{department}', function ($departmentId) {
return Employee::where('department_id', $departmentId)->get();
});
Laravel converts objects to JSON before writing them to the client.
As you said you have list of employees in a json file then First create a DB Seed to store your data in the DATABASE from that particular json file with the help of Seeding.
Lets say you made a table departments in the database and stored your data in all 5 columns(id, departments, name, profilePic, title), Then make a model that with the following command
php artisan make:model Department
For more details about models please visits on https://laravel.com/docs/5.4/eloquent#eloquent-model-conventions
Then simple detect that request through route and return the data as json:
Route::get('people/{department}', function ($departmentId) {
$data = Department::where('departments', $departmentId)->first();
return response()->json($data);
});
The very basic model query would be
Route::get('people/{department}', function ($department) {
return Employee::where('departments',$department)->get();
}
assume Employee is your model
.
Then Laravel automatically will convert your query to json.
FYI: You can also send this request to controller method the return like above