Return from Model.update() - javascript

I was checking Sequelize's examples and documentation the other day, and I came across:
Albums.update(myAlbumDataObject,
{ where:
{ id: req.params.albumId },
returning: true /*or: returning: ['*'], depending on version*/
});
I was very exited when I saw this. A very good way to avoid quite a few lines of code. What I was doing before was to get the object by Model.findOne(), re-set every field to their new values and invoke the instance method .save(), instead of using a static method like that.
Needless to say I was quite happy and satisfied when I saw that such static method existed, disappointing however, was to learn the method only returns the instance it updates if you're running Sequelize with PostgreSQL.
Very sad to learn that, as I'm using MySQL.
The method sure, issues a SQL statement containing the proper UPDADE string in it, but that's it. I don't know if it hit anything, and I don't have a copy of the updated data to return.
Turns out I need a Model.findOne() first, in order to know if that object exists with that id(and/or other filtering parameters), the Model.update() to issue the updates and finally a Model.findByPk() to return the updated model to the layer above (all of it inside a transaction, naturally). That's too much code!
Also during the update, if there's a UniqueConstraintError exception thrown (witch can be quite common), it's errors[] array carries no valid model 'instance', it's just 'undefined', so it complicates matters if you want details about what happened and/or throw custom error messages defined inside the models.
My questions are: Are there workarounds out there better than those I'm already implementing? Any sequelize plugins that may give me that with MySQL? Any sequelize beta code that can give me that? Is there any effort by the part of the sequelelize dev team to give us that? I'd appreciate any help given.
I'm running Sequelize version is 6.7.0, with Node.js v14.17.5.
Ps.: I even realized now that static Model.update() under MySQL will even update something that doesn't exist without complaining about it.

Related

Ember-Data: Intended usage pattern of DS.EmbeddedRecordsMixin

I've got a backend, that let's me read data asynchronously, but enforces embedding of certain child data (in lieu of transactions).
When using DS.EmbeddedRecordsMixin with ...
{
serialize: 'records',
deserialize: 'ids'
}
... (which should be the right thing to do given this backend) I've still got two questions.
(1) http://emberjs.com/api/data/classes/DS.EmbeddedRecordsMixin.html is very explicit, that DS.EmbeddedRecordsMixin shouldn't be mixed with async:true. From what I understand, the problem would be mixing async:true with embedded reading, not writing. On the other hand the documentation doesn't differentiate. Am I good with mixing async:true with above configuration (and is the documantion missing this case), or what is it that I am missing about async:true and writing?
(2) In my backend when deleting the parent, all children are delete as well. Deleting should be just one call for the parent. How do I do this on the ember end? I want to delete the parent and all children in the store, send one REST request and the success/failure of this request should be authoritative for all those records. Yet, the DS.EmbeddedRecordsMixin doesn't seem to help me in any way in that direction. Am I on my own, or what am I missing?
As far as your first question goes, I think you are good with mixing async:true and the EmbeddedRecordsMixin for your case. See this blog post and my example js-bin
As for 2, EmbeddedRecordsMixin leaves you on your own for that. But if you look at the code, all it does is push the records into the store when extracting them, so to reverse it all you should have to do is unload those records from the store. I'd keep a reference to the child records, then on a successful delete of the parent, clean up the children with record.unload(). Same example js-bin
To answer number (1) for anybody who may stumble upon this question later on: Encouraged by Kori John Roys' answer I've submitted a pull request to ember data to clearify the documentation. It was accepted, therefore now on the documentation only warns to mix async: true with embedded reading.

SailsJS override model methods

I am adding caching (redis) into my project and would prefer to code it into the model logic rather than the controller. I would need to overwrite the model method and add the logic for the caching there.
I know I can override certain methods like find and findOne but I'm not sure what to return.
Example (pseudo)
findOne: function () {
cache.get(key, function (err, data) {
if (data === null) // No cache data
// get the data and return it
else
// return the cache data
});
}
The problem is that these model methods dont just return the data, they return an instance of the model itself (for chaining).
Not really sure how to return the data and how to get it if it isn't already set. Has anyone ever done anything like this?
Caching is something that we'd love for Waterline, but at the moment the only way to really get what you want is to create your own adapter. Overriding find and findOne is not really feasible at this point, as there's no good way to access the underlying "parent" methods in case your cache turned up empty and you wanted to proceed with the query.
In your case, forking one of the existing adapters (like sails-mysql) to add Redis caching would probably be more constructive than starting from scratch. If one could add the caching layer as a separate, installable module (i.e. a dependency) of the forked adapter, it would be easier to replicate the functionality across other adapters, and eventually roll into the adapter spec itself. If anyone felt like tackling this it would be a great contribution! You might also ask in the Sails IRC channel (irc://irc.freenode.net/sailsjs) to see if anyone's already working on something similar.

How does one read JavaScript API like Mongoose

I'm a java developer. I really like to learn javascript. I'm finding it very difficult to pick-up a library and just learn/use it for two reasons:
1) There is no decent auto-complete. I've tried, eclipse, vjet, nodeclipse and webstorm...each has its own frustrating set of issues. Maybe the language is such that, autocomplete is super-difficult.
2) The API documentation is extremely confusing. I guess it is because I'm new to JavaScript.
For example, I wanted to figure what the callback function in mongoose.connect method does and how to declare it. So I checked the api doc. All it says is that the callback is a function...it doesn't say how many params it takes, what the values of the params are under various invocation scenarios...etc.
I feel like I'm missing something...
How does one go about reading these docs?
It's not you. I often find myself scratching my head about what the callback arguments should be. It's a problem with many JavaScript libraries.
However, in Node at least there is a convention that most libraries follow:
In node.js, it is considered standard practice to handle errors in asynchronous functions by returning them as the first argument to the current function's callback. If there is an error, the first parameter is passed an Error object with all the details. Otherwise, the first parameter is null.
For what it's worth, I haven't yet found an IDE that offers JavaScript autocomplete at anything nearly approaching the level of what's available for Java.
For the connect function, the callback passes an error argument given failure:
mongoose.connect('mongodb://localhost/dbname', function(err) {
if (err) {
// handle error
}
});
Generally, JavaScript tools are behind those for Java.
I feel like I'm missing something...
Me too. But, I think situation will change in 1-2 ears.
You can just wait for things to change or improve that you need by small step in a time.
Welcome to Nodeclipse.
It is time inefficient to solve problem only for one library (e.g. Mongoose),
but if there is web service like one for Node.js there is big chance for things change. Especially if you care enough to contribute, e.g. with ideas and materials or just raising an issue.

Can I make Rails' CookieStore use JSON under the hood?

I feel like it should be obvious doing this from reading the documentation, but maybe somebody can save me some time. We are using Ruby's CookieStore, and we want to share the cookie with another server that is part of our website which is using WCF. We're already b64-decoding the cookie and we are able to validate the signature (by means of sharing the secret token), all of that is great... but of course the session object is marshalled as a Ruby object, and it's not clear what is the best way to proceed. We could probably have the WCF application make a call to Ruby and have it unmarshal the object and write it out as JSON, but that seems like it will add an unnecessary layer of complexity to the WCF server.
What I'd really like to do is maybe subclass CookieStore, so that instead of just b64 encoding the session object, it writes the object to JSON and then b64's it. (And does the reverse on the way back in, of course) That way, the session token is completely portable, I don't have to worry about Ruby version mismatches, etc. But I'm having trouble figuring out where to do that. I thought it would be obvious if I pulled up the source for cookie_store.rb, but it's not (at least not to me). Anybody want to point me in the right direction?
(Anticipating a related objection: Why the hell do we have two separate servers that need to be so intimately coordinated that they share the session cookie? The short answer: Deadlines.)
Update: So from reading the code, I found that when the MessageVerifier class gets initialized, it looks to see if there is an option for :serializer, and if not it uses Marshal by default. There is already a class called JSON that fulfills the same contract, so if I could just pass that in, I'd be golden.
Unfortunately, the initialize function for CookieStore very specifically only grabs the :digest option to pass along as the options to MessageVerifier. I don't see an easy way around this... If I could get it to just pass along that :serializer option to the verifier_for call, then achieving what I want would literally be as simple as adding :serializer => JSON to my session_store.rb.
Update 2: A co-worker found this, which appears to be exactly what I want. I haven't gotten it to work yet, though... getting a (bah-dump) stack overflow. Will update once again if I find anything worthy of note, but I think that link solves my problem.

MongoDB query issue - error after second query

Right, I have this really weird problem, that is probably more related to how MongoDB works rather than a coding issue.
I'm making a website in Javascript (mostly) that is very heavy on jquery, using a MongoDB database and a nodejs server. I have users which have walls, and lots of information updates asynchronically. Because of this, I have to make dives into the database quite often, mainly to update things - for example if a user leaves a message on somebody's wall, or adding a friend.
The problem is, that once I make a query - trying to make another one just like it afterwards fail. They are literally identical (I tested this, copy&paste, they were a bit different first). It doesn't matter if I use find or update, the result is always null from the second query. I am closing the database after each dive, and returning as well just for good measure.
I can't find any issues anywhere where multiple queries to the same place fails after one succeeds. It's as if there is a lock somewhere, because I'm 100% sure my query is correct, and shouldn't return null. Not even hard coding works. The first query works perfectly. Same data, same collection.
So, my question is: does MongoDB have some query cache that could be blocking the query, or is there something else I've missed in how the queries work? Do you have any good tips and hints when having to do multiple database queries?
I get TypeError: Cannot read property '_id' of undefined as a result of the query returning null.
I hope this is enough information for anyone to have a clue what's wrong. I'm not providing any code as I think this is more a matter of me not really getting how MongoDB works rather than a coding issue.
Problem is now solved. I have no idea what caused it, but I rewrote some large chunks and that did the trick. Thanks for your time!

Categories

Resources