Bookshelf.js: Cascade save? - bookshelf.js

Does Bookshelf support cascading related entities on save?
I see that we can declare associations on the model.
However, for instance, when I have a Book
var Book = bookshelf.Model.extend({
tableName: 'books',
pages: function() {
return this.hasMany(Page);
}
});
Which has a non-null pages field, and I save a Book, it tries to store the pages array as a single JSON LOB object into the DB, rather than performing a cascade save on Pages's table.
The documentation doesn't mention anything about cascading.
Can we do cascade on save with Bookshelf and if so, how?

Related

#Id field annotation for storing POJO in Firebase Firestore?

We have a complex JSON having multiple sub-objects inside main object.
For example:
dept: {
name: Dept1,
emps: [
{
empCode: 001,
empName: Emp001
}
]
}
If we use db.collection("dept").add(deptPojo) then it auto creates "emps" subcollection and auto assigns document id for each emp object.
But we want empCode to be assigned as document id for each emp document.
Is this achievable? How? Is there any #Id annotation in firebase firestore api?
Updated
Now you can do it using #DocumentId from firebase.Just add it in your POJO class
There is currently no way to indicate the ID using an annotation, but I believe the Firebase team is looking into a solution for that.
Sorry guys, my bad!
I was under impression that array of emps inside dept in my example above will end up with creating sub-collection emps having each entry in an array an auto-generated document id.
But later I understood that, I was wrong in this assumption.
The behavior is as follows.
If you have nested objects (i.e. parent having a field of type List or Map.
Then they are stored as an array in firestore instead of creating a dedicated sub-collection.
Means in case of saving pojo object, firebase doe's not auto create sub-collections.
As show in screenshot here... devices is a Map of device objects but it stored as array.
Thanks.

AWS AppSync - Creating Resources for schema missing custom types and enums

I understand that enums are not standard type in Dynamo: https://forums.aws.amazon.com/thread.jspa?messageID=836386
However, what is the exact resolution here?
How are we supposed to appropriately represent relations with the generated code?
-- Am I missing something or is the generated code correct and we need to create some custom fields in the dynamo tables and then rewrite the queries?
Example:
type Competition {
id: ID!
name: String!
creator: UserProfile!
startDate: String!
endDate: String!
competitionType: CompetitionType!
competitors: [UserProfile]!
prize: Prize!
}
A competition is created by a user, has a type, a prize, and has competitors. When create resources for this table, the code is clearly missing any information that is derived out of the custom types or enums. Complex schemas will always have this type of structure, so I'm a bit confused on the outputted code and right direction from here.
extend type Mutation {
createCompetition(input: CreateCompetitionInput!): Competition
}
input CreateCompetitionInput {
id: ID!
name: String!
startDate: String!
endDate: String!
## Missing info
}
When AppSync generates the schema automatically it skips these as they are intended to be added manually with additional resolvers. You can define a new query that is attached to each of the custom or enum fields, but the data you are referencing will need to be stamped with something that is unique to the competition so that it can be queried on in relation to this type (as dynamoDB isn't a relational db).
When creating a new Competition you will need to update child fields with something unique to that competition. I.e. each UserProfile that needs to be tracked as a competitor gets stamped with this Competitions ID. Mutations for each of the custom fields need to be handled separately.
This article helped me solve this same question: https://keyholesoftware.com/2018/05/17/go-forth-and-appsync/.

Meteor won't publish collection with id's of type ObjectID

One of my collections contains documents with ObjectID's instead of Meteor style _ids's that are generated by Random.id().
I get error output in the server console saying 'Error: Meteor does not currently support objects other than ObjectID as ids' when I try to publish/subscribe to a subset of the collection.
This used to work fine, but appears to be problematic in Meteor 1.4.3.2. Does anyone have a pointer how to solve this issue?
The mongodb supports the _id field as a normal field, like this:
{
_id: "sa09d8asd98asd9sad8",
otherfield: "jdlskfjsdlk"
}
And supports the _id field as an ObjectID field, like this:
{
_id: ObjectID("sa09d8asd98asd9sad8"),
otherfield: "jdlskfjsdlk"
}
But in Meteor Apps, the _id field as an ObjectID is not supported and it will not work in publications and subscriptions functions. You will need to change your ObjectID's fields for normal _ids fields.

Prepare Query for Search Multiple Collections using Meteor?

In my application 2 collections are there.
1.profile - Fields are : username,id,city and postalcode
2.material - id,version,descrption and usage
In single collection we use as shown below :
var query = {};
query.username = 'xxxx';
query.city= 'yyyy';
Need Multiple Collections Query as shown below data?
Need query for to pass username and city in profile and descrption in material?
MongoDB does not support joins in the way a relational DB (e.g., MySQL) does. There are a number of materials available on the subject, principally...
Discover Meteor's tutorial on reactive joins
Reactive and Non-Reactive Join with MongoDB
This HackPad about reactive join packages
What these all boil down to is this: It's not native in MongoDB, but with Meteor, you have three options:
Use a package to do it for you
De-normalize (include one collection entirely within the other)
Do it yourself with publication and routing
From your comment:
In Profile Id is there and material are also id there.So these two are same
it sounds like the id fields are what you'd like to join by -- the second option (de-normalize) here is really easy, if you can get away with it. Rather than having two Collections, have one Collection in the following format:
{
username,
material: {
version,
description,
usage
},
city,
postalcode
}
and then query like so:
Profiles.find({username: 'xxxx', city: 'yyyy', "material.description": "zzzz"});
This has obvious tradeoffs in terms of storage efficiency and re-usability (for instance, if your material Collection is used elsewhere, you can't really just embed it in the profile Collection). Note that this also works if you have many materials that have the same description.
If you need to keep them separate, you can narrow down the set of fields to look in manually (option 3) -- you can see how I did that on this MeteorPad, but the basic idea is in your publish function, query one Collection first, then use that information to query the other:
// Return all profiles with a certain material description -- includes multiple materials.
Meteor.publish('profiles', function(username, city, material) {
var materialIds = Materials.find({description: material}).map(function(mat) { return mat._id });
return Profiles.find({material: {$in: materialIds}, username: username, city: city});
});
There are a lot of choices for packages, so I will leave it up to you to find the one most suited to your needs and read the documentation if that's the route you choose.

Many to many relationship with junction table in Entity Framework?

I'm trying to create a many-to-many relationship in Entity Framework (code first), according to the following post: Database design for limited number of choices in MVC and Entity Framework?
However, I can't get it to work properly, and I'm sure I'm doing something very simple the wrong way. Here's the diagram I have no from my attempts:
The point of the junction table is that I need to have an extra property, Level, in the relationship, so I can't just go with a direct relationship between Consultant and Program. I added the ConsultantProgramLink entity manually in the designer, and then added associations to Program and Consultant respectively, selecting to add a FK for each, and then made them both primary keys. But when I do it like this it doesn't work as I expected:
If I had done a direct association between Consultant and Program, I would have been able to refer to, say, Consultant.Programs in my code. But that doesn't work now with the junction table. Is there any way to remedy this, or do I always have to go through the junction property (Consultant.ConsultantProgramLink.Programs)? In any case, even if I do try to go through the junction property it doesn't help. I can do Consultant.ConsultantProgramLink in my code, but another dot doesn't give me the navigation property Programs (which for some reason also became simply Program, why? Can I just rename them if I eventually get access to them at all?).
So what am I doing wrong? Why can't I access the properties through dot notation in my code?
Once you model a junction table as an entity you indeed lose direct many-to-many relation between Consultant and Program. That is how it works. You will either have direct many-to-many relation or additional properties in the junction table. Not both. If you want both you can try creating custom Programs property on Consultant and use linq query to get related programs:
public IEnumerable<Program> Programs
{
get
{
return this.ConsultantProgramLinks.Select(l => l.Program);
}
}
The example is also the explanation of your last problem. You can't have Program property on ConsultantProgramLink because it is a collection of related entities, not single entity (it should be called ConsultantProgramLinks). The property in ConsultantProgramLink entity is called simply Programbecause it represents single entity not collection.
Edit:
If you need each Program to be automatically associated with each Consultant you must enforce it when you are going to create new Program. Having junction table exposed as separate entity will probably allow you achieving it easily:
var program = new Program();
...
context.Programs.AddObject(program);
var ids = from c in context.Consultants
select c.Id;
foreach (var id in ids)
{
var link = new ConsultantProgramLink
{
ConsultantId = id,
Program = program
};
context.ConsultantProgramLinks.AddObject(link);
}
context.SaveChanges();
If you add new Consultant you will have to create links to all programs in the same way.
The disadvantage is that if you have for example 1000 consultants this construct will create 1001 database inserts where each insert will be executed in separate roundtrip to the database. To avoid it the only option is either use stored procedur or trigger on Program table.

Resources