Embedded belongsTo to an unsaved record creates two POST request - ember-data

I got an issue when i try to add an embedded belongTo to an unsaved record. When committing the transaction, I got two POST request. I don't know if I'm doing something wrong or not...
Here's my models and mapping:
Comment = App.Comment = DS.Model.extend({
title: DS.attr('string')
});
Group = App.Address = DS.Model.extend({
name: DS.attr('string')
});
Post = App.Post = DS.Model.extend({
title: DS.attr('string'),
comments: DS.hasMany(Comment),
group: DS.belongsTo(Group)
});
DS.RESTAdapte.map(Post, {
comments: { embedded: 'always' },
group: { embedded: 'always' }
});
My transaction
var transaction = store.transaction();
var post = transaction.createRecord(Post, {
title: 'This post is unsaved'
});
post.get('comments').createRecord({
title: 'This embedded record is also unsaved'
});
post.set('group', Group.createRecord({
name: 'My Group'
}));
transaction.commit();
Then I will have two POST request, one on '/post' wich is good and another one on '/group'.
Am I doing something wrong ? Thanks you !

It seems to me that you have 2 transactions:
the one that you create manually and that contains the post and the comments
the store's default one onto which you create the Group
You probably want your code to be like that:
post.set('group', transaction.createRecord(App.Group, {
name: 'My Group'
}));
Group.createRecord will use the store's default transaction.

Related

TypeORM select data from nested relations

Using
await this.budgetRepository.createQueryBuilder("budget")
.leftJoinAndSelect("budget.contact", "contact")
.leftJoinAndSelect("contact.photo", "contactPhoto")
.getMany();
I get a list with objects like this:
Budget {
id: 1,
unnecessary_property1: something,
contact: Contact {
unnecessary_property2: something,
photo: Photo {
unnecessary_property3: something,
url: "url.com"
},
},
}
But I want to select only the necessary properties in the nested objects (relations) and get a list of objects like this:
Budget {
id: 1,
contact: Contact {
photo: Photo {
url: "url.com"
},
},
}
How is that possible with TypeORM?
This is possible but we have to select everything manually with .select()
await this.budgetRepository.createQueryBuilder("budget")
.leftJoinAndSelect("budget.contact", "contact")
.leftJoinAndSelect("contact.photo", "contactPhoto")
.select(['budget.id', 'contactPhoto.url']
.getMany();
If you're using repository pattern that you will be achieve the similar result with:
await this.budgetRepository.find({
relations: ["contact", "contact.photo"]
})
You would have to use the .select() function and pass the given properties you want for each entity.
for your example:
const user = await createQueryBuilder("budget")
.leftJoinAndSelect("budget.contact", "contact")
.leftJoinAndSelect("contact.photo", "contactPhoto")
.select([/* everything from budget */, 'contact.photo.url'....]) // added selection
.getMany();

Youtrack check if user has permissions

I'm trying to create a Youtrack workflow where only a specific role is allowed to edit the Kanban state to ready-to-pull when the current issue is in backlog. I wasn't quite able to get it correctly working, keeps throwing exceptions but I'm unable to read the full exception.
I tried to create the current workflow code:
var entities = require('#jetbrains/youtrack-scripting-api/entities');
var workflow = require('#jetbrains/youtrack-scripting-api/workflow');
exports.rule = entities.Issue.onChange({
title: workflow.i18n('Block change in Kanban stage for issues that are in backlog'),
guard: function(ctx) {
return ctx.issue.isReported && ctx.issue.fields.isChanged(ctx.KanbanState);
},
action: function(ctx) {
var issue = ctx.issue;
if (!ctx.user.hasRole('project-admin', ctx.project)) {
workflow.message('U dont have the correct permissions to do this');
ctx.KanbanState = ctx.KanbanState.Blocked;
}
},
requirements: {
Stage: {
type: entities.State.fieldType
},
KanbanState: {
name: 'Kanban State',
type: entities.EnumField.fieldType,
ReadyToPull: {
name: 'Ready to pull'
},
Blocked: {}
}
}
});
Most of this is a copy from the Kanban change workflow that blocks moving the issue to a new stage when the kanban state isn't set to "Ready-to-Pull". I basically want the exact same, but I want to only allow project admins to change the kanban state to "ready-to-pull" when the current stage is "Backlog". The current code only checks the permissions at the moment, but I started getting stuck there already.
To implement this task, I suggest you use the workflow.check method, for example:
workflow.check(ctx.user.hasRole('project-admin', ctx.project), 'U dont have the correct permissions to do this');
I hope this helps.
Seeing as in our current situation we only need to disable a single person to not be able to change the Kanban states when new tickets are set, we have the following solution:
exports.rule = entities.Issue.onChange({
title: workflow.i18n('Block change in Kanban stage for issues in backlog stage'),
guard: function(ctx) {
var issue = ctx.issue;
return issue.fields.isChanged(ctx.KanbanState);//Runs when Kanban state changes
},
action: function(ctx) {
var issue = ctx.issue;
//Check if user has changed the kanban state to ready to pull while the current stage is backlog.
if (issue.fields.Stage.name == 'Backlog') {
//Current stage is backlog
if (issue.fields.KanbanState.name === ctx.KanbanState.ReadyToPull.name) {
//Kanban state was changed to ready to pull;
var target = '<useremail>';
workflow.check(ctx.currentUser.email == target,
workflow.i18n('No permissions to change the Kanban state.'));
issue.fields.KanbanState = ctx.KanbanState.Blocked;
}
}
},
requirements: {
Stage: {
type: entities.State.fieldType,
Backlog: {},
Development: {}
},
KanbanState: {
name: 'Kanban State',
type: entities.EnumField.fieldType,
ReadyToPull: {
name: 'Ready to pull'
},
Blocked: {}
}
}
});
However I checked the answer of #Oleg Larshun and his answer worked as well. replacing the email section with:
workflow.check(ctx.user.hasRole('project-admin', ctx.project), 'U dont have the correct permissions to do this');

Cannot get new array to save

I am working on getting a blog set up and I am having trouble getting my comments data associated with the individual blog post. I am using Mongoose and Express. I am trying to create a new posts and push it to the blog array, but the association is not saving. I can see both the comment and blog objects in my DB individually when I pull up the Mongo shell, but they are not associated in the DB. However, they are showing correctly in the console in the my route.
Here are my two relevant schemas that are up in different files.
Comment schema:
var mongoose = require("mongoose");
var commentSchema = new mongoose.Schema({
author: String,
desc: String,
posted: {type: Date, default: Date.now()}
});
module.exports = mongoose.model("Comment", commentSchema);
Blog schema:
var mongoose = require("mongoose");
var blogSchema = new mongoose.Schema({
author: String,
title: String,
desc: String,
posted: {type: Date, default: Date.now()},
comments: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Comment"
}
]
});
module.exports = mongoose.model("Blog", blogSchema);
Route:
app.post("/blogs/:id/comments", function(req, res){
Blog.findById(req.params.id, function(err, blog){
if(err){
// console.log(err);
res.redirect("/blogs");
} else {
Comment.create(req.body.comment, function(err, comments){
if(err){
console.log(err);
} else {
blog.comments.push(comments);
blog.save();
console.log(blog);
res.redirect("/blogs/" + blog._id);
}
});
}
});
});
console results from above:
{ _id: 5a3ef348fcdd624a0c8416fb,
title: 'Ah, a new post!',
author: 'Lefty',
desc: 'Here we are trying to see about fixing the issue with comments not being associated to the blog posts, but still being created.',
__v: 0,
comments:
[ { _id: 5a3f06c0f33db14984baca92,
desc: 'Save the turtles.',
author: 'April',
__v: 0,
posted: 2017-12-24T01:45:16.864Z } ],
posted: 2017-12-24T00:21:34.514Z }
Here is the information in my Mongo shell:
> db.blogs.find()
{ "_id" : ObjectId("5a3ef348fcdd624a0c8416fb"), "title" : "Ah, a new post!", "author" : "Lefty", "desc" : "Here we are trying to see about fixing the issue with comments not being associated to the blog posts, but still being created.", "comments" : [ ], "posted" : ISODate("2017-12-24T00:21:34.514Z"), "__v" : 0 }

Mongoose relation not working both ways

I can't get a relationship running between my Rides and Comments controller in my app (built using the yeoman angular-fullstack generator).
Comment model:
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var CommentSchema = new Schema({
name: String,
comment: String,
active: Boolean,
ride: { type: mongoose.Schema.Types.ObjectId, ref: 'Ride' }
});
module.exports = mongoose.model('Comment', CommentSchema);
Ride model:
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var RideSchema = new Schema({
name: String,
distance: String,
climb: String,
rating: String,
active: Boolean,
comments: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Comment' }]
});
module.exports = mongoose.model('Ride', RideSchema);
Accessing /api/comments/ gives me a correct result, containing a related Ride:
{"_id":"54ce818f8c2889da58b01e19","name":"NAAM","comment":"COMMENT","ride":"54ce69647a78532057aa98e0","__v":0}]
Accessing /api/rides/ gives me the following result, without the corresponding Comments:
[{"_id":"54ce69647a78532057aa98e0","name":"Ride test ingevuld","distance":"4000","climb":"1200","rating":"1","__v":0,"comments":[]}]
Can anyone tell me what i am doing wrong?
Example from one of my projects:
exports.insertRoom = function(req, res) {
var id = req.body.id;
var r = req.body.room;
var room = new Room({name: r.name});
Floor.update(
{_id : id},
{
$push: { rooms: room}
},
{upsert:true},
function(floor, err)
{
res.sendStatus(200);
}
);
};
As far as I'am concerned it doesn't work like that. Your comments got it's ride, and your ride got it's comments. I think, you should remove
ride: { type: mongoose.Schema.Types.ObjectId, ref: 'Ride' }
and keep comments inside ride collection.
comments: ['Comment']
It is more objective solution as it supposed to be in MONGO DB which was designed for objective(hierarchial) data.

Transaction with Sequelize doesn't work

I want to build a simple webform where you can enter a persons firstname, lastname and select multiple groups for this person (but one for now)
I'm using node.js and sequelize to store the person in a MariaDB -Database.
Sequelize created the tables Persons, Groups and GroupsPersons according to the defined models.
var Sequelize = require("sequelize");
var sequelize = new Sequelize(config.database, config.username, config.password, config);
var Group = sequelize.define("Group", {
name: {
type: DataTypes.STRING,
allowNull: false
}
}
var Person = sequelize.define("Person", {
firstName: {
type: DataTypes.STRING,
allowNull: false
},
lastName: {
type: DataTypes.STRING,
allowNull: false
}
}
Person.belongsToMany(Group, {as: 'Groups'});
Group.belongsToMany(Person, {as: 'Persons'});
Because creating the person and assigning it into a group should be handled atomically in one step I decided to use a transaction, shown in the docs here:
http://sequelize.readthedocs.org/en/latest/docs/transactions/#using-transactions-with-other-sequelize-methods
var newPerson = {
firstName: 'Hans',
lastName: 'Fischer'
}
var id = 3 // group
sequelize.transaction(function (t) {
return Person.create(newPerson, {transaction: t}).then(function (person) {
return Group.find(id, {transction: t}).then(function(group){
if (!group) throw Error("Group not found for id: " + id);
return person.setGroups( [group], {transction: t});
})
});
}).then(function (result) {
// Transaction has been committed
// result is whatever the result of the promise chain returned to the transaction callback is
console.log(result);
}).catch(function (err) {
// Transaction has been rolled back
// err is whatever rejected the promise chain returned to the transaction callback is
console.error(err);
});`
But for some reason neither function (result) {.. for success nor the function in catch gets called. However, the complete SQL queries of the transaction were generated except COMMIT, so nothing was inserted into the db.
If I put it like this
return person.setGroups( [], {transction: t});
the transactions succeeds, but with no inserts into GroupsPersons of course.
Any ideas or suggestions?
Thanks for help!
{transaction: t} was misspelled, it works now