Jaydata will object still exist after table drop and rebuild - javascript

Lets say I have two tables task and person.
//Create related data
todoDB.Todos.add({
Task: "Your task",
Person: new Person({Name: 'Peter'});
});
todoDB.saveChanges();
I'm trying to implement a way of keeping all the client and server data in sync.
Lets say I changed the schema of person and need to rebuild that table --> I drop person and rebuild it with the new schema.... re-populate it with data including a person with name=Peter. Will "Your task"'s person attribute still link to that same person, or will that attribute need to be rebuilt. I plan use an id attribute in reality and not name, and Id will be a key value.

If your sync happens only one-way direction, you can use the IDs from the server, but if you create entities on the client and you want to sync back to server, the GUID reference types are the way to go to have the same identifiers on the client and the server without conflicts.

Related

How to allow a user to query all rows or just selected ones?

I've been looking for this but i have no idea about the name of this.
I am creating a data model on MySql and i have a table called users and i want to restrict the queries from each user, for example, allow to read all the rows from the clients table or only allow them to query some selected clients. It's like a filter but my question is, how can i save the name of the clients for each users or allow them to have access to all the clients?
My first idea was create a Many to Many relationship but when i create a new client i need to update the table for each user that have the options to query all the clients.
My second idea was create a table with a column called selectedClients with array data type and save ["all"] and whith an "if" make the query and if i selected various clients, in that filed will be save the id of the clients such as ["clientID1", "clientID2"] and after, in my middleware i will query the table only with the id's of that field. But the problem is that it's not a good practice i think and when deleted a client, i need to deleted for each field of that id.
How can i implement this?
Database-wise, what you want is a many-to-many relationship. Many users can access many clients. So you'll have a users table, a clients table, and a usersclients table (or whatever you want to name it). The usersclients table would map users.id (presuming id is the name of the primary key) to clients.id. There would be 1 row in usersclients for every client that every user can access.
As for users that can view all clients, my initial thought is to have that set as a flag on the user. Then, when you're building the list of clients, do something like:
(pseudo-code, please excuse any c# influence)
let viewableClients = [];
if( user.canViewAllClients ) {
clients = queryToGetAllClients();
} else {
clients = user.UserClients.forEach(uc => uc.Client);
}

Redux - Remove object from store on http response error

Consider the following flow:
I have a page with a list of "products" and a modal to create a single "product". I open the modal, fill the form and submit the form.
At this point, I dispatch an action CREATING_PRODUCT, add the product to the store and send the http request to the server.
I close the modal and display the list of results with the new product.
Let's suppose I receive an error response from the server.
Desired behavior:
I would like to display an error, remove the project from the list, re-open the modal and display the form already filled.
Question
How can I find that project and remove it the list? I don't have an id (or a combination of unique properties) to find that project in the store. I don't see a clean way to link a request/response to that "product" object in the store.
Possible solution
The client adds a "requestId" into the project before adding it to the store. On response error, I dispatch a generic "CREATE_ERROR" and I remove the project with that requestId from the store.
Extra
Same problem with edit and delete. For example during a delete should I keep a reference to the deleted project with the requestId in the store, until the http request is successful?
I bet it is a problem with a common solution, but I can't find examples.
Thanks!
In general, your Redux store should be modeled somewhat like a relational database, in that every time you have a list of data models, each element of the list should have its own identifier. This helps a lot when dealing with more complex data schemes.
You should probably store your projects as an object, something like:
{
// ...other store properties
projects: {
"_0": { // ... project properties }
"_1": { // ... project properties }
// ...more projects...
},
}
This way, whenever you need to mess with an existing project, you can just reference its id and use projects[id] to access that project. This would also solve the edit and delete cases, as you could just pass the IDs around as handles.
I like this short piece on why your Redux store should be mostly flat and why data should always have identifiers very much. It also talks about using selectors to "hide" your IDs away, which may or may not be useful for you.
In your case, as you are getting IDs from a server, you could have an ID prefix which indicates unsaved values. So your projects object would become something like:
projects: {
"_0": { // ... }
"_1": { // ... }
"UNSAVED_2": { // ... }
}
This way, you could easily identify unsaved values and handle them when an error occurs, still get the benefits of generating temp IDs on the client-side in order to revert changes on error, and also warn your user if they try to leave your app while their data still hasn't been synchronized - just check if there are any "UNSAVED" IDs :)
When you get a response from the server, you could change the "UNSAVED_suffix" ID to an actual ID.

Backbone.model.save(): POST(create) / PUT(update) logic doesn't match application logic - how to avoid PUT in certain situations?

I'm creating an Web-Application (Frontend and Backend, so both are under my control) using Backbone and Pyramid, being connected via a RESTful API.
During development I encountered a problem several times by now, where Backbone PUTs (=updates) a new model, while it actually should POST (=create) it.
Backbone decides whether to POST or UPDATE a model depending of the presence of an ID-field (if no ID present in the current model: -> POST/create | if so: PUT/update).
However I encountered several situations by now, where this behaviour doesn't match my application logic.
Let's say our main model (and its objects being persistently saved in a relational database in the backend) is called Foo, having fields like id, field_1, field_2.
Example #1: Creating a template or preview of Foo: Before creating (=POSTing) an object of Foo, I can create and show a preview to the user and/or save it as a template.
While doing so, the backend (in case of the preview: temporarily) adds the object to the database and returns the full model - including an ID in its HTTP response - back to Backbone.
Template- and Preview-objects of Foo are (temporarily) saved into the same table, as final objects (column type indicates its type (0 = final/live, 1 = preview, 2 = template)).
When now - after previewing / saving as template - trying to actually CREATE an object of Foo, the Backbone model already has the ID field set and actually PUTs and updates the template or not-anymore-existing preview, instead of POSTing and therewith creating a new Foo inside the database (as intended).
=> solution #1: calling POST /json/preview does not return the ID field, so Backbone doesn't get confused.
=> solution #2: overriding parse() of Foo in Backbone-model to kick out ID field from response
.=> kinda works
Example #2: Having a Periodic model, which refers to a Foo-template. Intention of a Periodic is to offer the user the possibility of semi-automatically creating a new Foo object based on a Foo-template every X months.
Now there is a call GET /json/periodics, which returns all Periodic-objects with its nested Foo-objects (Foo-templates), including their IDs, e.g. [{'interval': 12, template_id: 42, template: { 'id': 42, field_1: 'foo', field_2: 'bar', .. } , { .. } , .. ].
On the frontend the user now can periodically confirm (or skip) creating a new Foo-object, by issuing: periodics[X].template.save() which however again PUTs and therewith updates the Foo-model, instead of POSTing and creating a new one (as intended).
Here again (as in example 1), I could strip out the ID field of Foo - either in the backend or frontend.
However there are situations, where I need the id-field of templates, e.g. when actually editing them, so here I'd need two calls (GET /json/templates_WITHOUT_FOO-IDs and GET /json/templates_WITH_FOO-IDs). which also sounds far from right.
Question is: What's the right (and consistent) way of avoiding Backbone falsely assuming a model should be PUT instead of POSTed in certain situations / views?
Backbone's save and fetch methods just make calls to the Backbone.sync
method, which in turn is just a wrapper for an ajax call. you can pass
in ajax parameters using the save function without having to actually
extend it. basically ends up being something like this:
model.save({attributes you want to save}, {type:'POST', url: 'apiurl/model/:id/played'});
You would have to do this every time though so it is probably better practice to extend Backbone.sync for your model.
The Backbone website has a bit of information about what I'm talking about as far as the Backbone sync and save taking ajax options. There are also a few examples I've seen on extending sync but I can't seem to track them down at the moment.

How to save multiple records in the saveRecord function through nlapi methods?

I have customized the default promotion form in which if a user clicks on a particular promotion the form will show dynamic elements using jquery ( as we have not created the fields or lists/records for this requirement).
so based on the data we may need to create multiple records while submitting the form. I have created the saveRecord() function in js file which is already mapped with the form. In that am trying to create promotionRecord dynamically. But cant save the record I am getting "the items you requested in the record have been deleted since you retrieved the form" error. What could be the problem and is it possible to save multiple record in single form submit?
departments = Object.keys(samplePromotions);
$.each(departments, function(key,value){
console.log(samplePromotions[value]);
promotion = nlapiCreateRecord('customrecord_promotion');
console.log(promotion);
//required
promotion.setFieldValue('name','jAVASCRIPT pROMOTION cREATION_'+value);
promotion.setFieldValue('custrecord_px_promotion_id','js_prom_creation_'+value);
id = (Math.round(new Date().getTime()/1000));
console.log(id);
promotion.setFieldValue('id',id);
var id = nlapiSubmitRecord(promotion);
Not sure if this is the problem in your code, but to answer your question you can only submit one record with the API.
I would just create an array and loop through the length of it and call nlapiCreateRecord and the nlapiSubmitRecord for each one.
-- Edit
Not sure about this, but this looks weird to me to. You are setting the id using setFieldValue method, which I believe is the external Id. Then you are setting setting id again with the nlapiSubmitRecord call. This returns the internal Id. Maybe that is causing issues as well?
Must be this line
promotion.setFieldValue('id',id);
The id field on the record object contains the internal id of the record. This is generated by NetSuite when you create a record.

Which is worse? One more db acess or one outdated value?

PROBLEM
I'm running an application with AngularJS, Node JS, Express and MongoDB. I'm acessing MongoDB trought mongoose. My problem is that I have a lists of swords, each forged by someone. But, to access someone's profile, I need to use the ID of someone. The ID is unique. But I can't display the link as something link '352384b685326vyad6'. So, when someone create's a sword, I will store his or her name within the sword info.
To display a list of swords, for example, I could do something like this:
<div ng-repeat='sword in swords'>
<p> Sword name: {{sword.name}} </p>
<p> Author: <a href='#/user/{{sword.createdByID}}'> {{sword.createdByName}} </a> </p>
</div>
But, if the User changes his name, the sword will not update his creator name accordingly. What should I do? I have thought of some solutions, but I don't know which and if any could solve this in a good manner.
When someone changes own name, I could make a POST request with the new username and the ID, updating all sword that has createdByID equals to user ID. But I see this too strange.
SwordModel.find({ createdByID: req.body.id}, [...]);
When loading the swords in the controller via GET request, make another GET request for each sword and update sword.username based on the sword.createdById.
UserModel.findById(req.body.id), [...]);
Forget UX and use ugly links.
I want to know how can I maintain the username of each sword updated without affecting too much my DB Thanks for any advice.
MODELS - Just for reference.
sword.js
var mongoose = require('mongoose');
var SwordModel = mongoose.model('SwordModel',
{
name: String, //Sword's name
createdById: String, //ID of the user who created.
createdByName: String //Name of the user
});
module.exports = mongoose.model('SwordModel', SwordModel);
user.js
var mongoose = require('mongoose');
var UserModel = mongoose.model('UserModel',
{
name: String, //Name of the user.
ID: String //ID of the user.
});
module.exports = mongoose.model('UserModel', UserModel);
You can do it by referencing the User inside Swords if you make use of Mongoose schema.
After you make a reference to another schema you can use populate method to get the desired results.
Example (May be not exactly, but something similar to following) :
Sword Schema:
var swordSchema = new Schema({
name: String,
createdBy: {type: mongoose.Schema.Types.ObjectId, ref: 'User'}
});
Make model using the schema :
var swordModel = mongoose.model('Sword', swordSchema);
Find what you are looking for using populate.
See full documentation for populate here - http://mongoosejs.com/docs/populate.html
EDIT: note that I am recommending to keep user's name only in User model and just reference it.
I think we have less of a technical problem and more of a conceptual problem here.
Constraints
I take it for granted that...
users may change their usernames
usernames are unique
you only need to provide a link to a user, displayed by name
Furthermore, I will use plain JSON and MongoDB and trust that you can translate this to Mongoose.
The solution
Albeit users can change their usernames, this is not going to happen often. The more common use case is that you need to link to a username. So we first need to find out how to efficiently deal with that use case.
Since you only need the name of the smith for a given sword, there is nothing wrong with a sword model like
{
_id: new ObjectId(),
name: "Libertas",
smith: "Foobar"
}
to efficiently find "Foobar" in the users collection, we simply add an index here (if not already done):
db.users.createIndex({username:1}, {unique:true})
and your service can query efficiently by using
db.users.find({name: "Foobar"})
No need to save the _id of the user within the sword document, but still you can query for it efficiently.
Dealing with a change in the username is a rather rarely executed use case, so optimizing here does not make sense. However, if a user changes his or her username, your service can easily achieve that through
db.swords.update(
{ smith:"Foobar" },
{ $set:{ smith: "CoolNewUsername" },
{ multi: true, writeConcern: { w:1, j:true }
)
The last line of the above needs a little explanation. The multi: true option tells MongoDB to change all documents matching {smith: "Foobar"}, not only the first one found, that's easy to understand. But why to set the write concern to journaled? The first reason for it is that regardless of the write concern configured for the connection (which may even be unacknowledged), we need those changes to be durable. However, we usually do not need to have the changes to be propagated to more replica set members, so the chosen write concern gives you the best performance while still you can be sure that the changes were synced to a disk. If you need higher durability, of course you can set the write concern to {w:2} or {w:"majority"}.
Advantages
For the most common use case of this relationship (displaying a link to the user who forged a given sword), all information needed to do this is included in the sword's document, preventing possibly unnecessary queries.
Still, the smith of a given sword can be queried efficiently if a user clicks said link.
Changing a users name is possible and can be achieved pretty efficiently and durable
Disadvantages
The main disadvantage here is that you actually have to modify all affected swords when a user changes his or her username, whereas with a Mongoose reference that would be unnecessary. However, since this is a rare use case and using populate would result in the whole user document to be loaded where only the users name is needed, I see this disadvantage as negligible. Basically you are trading to cut down the queries needed for a common use case by half against the need for a manual update which occurs rather rarely.
I fail to see any other disadvantage.

Categories

Resources