I have an instance where I have Users and Roles. I have the following:
var User = sequelize.define("Users", {
username: DataTypes.STRING,
password: DataTypes.STRING,
});
var Role = sequelize.define("Role", {
role: DataTypes.STRING
});
var UsersRole = sequelize.define("UsersRole");
User.belongsToMany(Role, {through: UsersRole});
Which creates a UsersRoles table in the DB for me with a UserId and RoleId column. This is all working fine, but now I want to be able to update a users role, I can't work out quite how to do this! I've tried the following with no luck so far:
models.Users.findAll({
where: { id: req.params.id },
include: [{ all: true }]
}).then(function(dbUser){
dbUser[0].Roles[0].updateAttributes({
RoleId: req.body.role,
},
{
where: { UserId : req.params.id }
}
).then(function (result) {...
In summary, all I want to do is be able to change a users role, so update the 'UsersRoles' table and change the RoleId for a given UserId. I can't quite seem to figure out how to get to the UsersRoles table via any sequelize syntax!
I could write some raw SQL but that doesn't feel right?
EDIT
I just want to update a users role, if the table has:
| UserId | RoleId |
-------------------
| 1 | 1 |
I would like to be able to change it to:
| UserId | RoleId |
-------------------
| 1 | 2 |
but I can't quite figure out the code to do this!
There is no need to interact with the join table directly - You can simply do
user.setRoles([newRole]);
http://docs.sequelizejs.com/en/latest/api/associations/belongs-to-many/#setassociationsnewassociations-options-promise
Notice that I'm passing an array, since users can have many roles - set removes all currently assigned roles. If you want to add a new role and keep the existing, use
user.addRole(newRole);
you are updating RoleId but you have not defined it. If you don't define a primary key on a table the by default Sequelize defines a primary key by name if id, so you should do id: req.body.role.
Related
I'm trying to create a new entry into my table that has a relationship called "organizationAdmins". In that relationship is another relationship called "Role". I need to look up Role based on some criteria to connect. I've tried many different iterations to get this to work but the best I have is this, which doesn't work unfortunately...
let current_organization = await prisma.organization.create({
data: {
name: organization.name,
organizationAdmins: {
create : [{
account_id: account_id,
Role: {
connect : {
where: {name:"OWNER", owner:1, role:1, write:1, read:1}
}
}
}]
}
},
});
So if I were to take the SQL example for what I'm trying to do it would be this...
select id from role where name='OWNER' and owner=1 and role=1 and write=1 and read=1
I could pull the role_id like I did for account_id separately. But I'm trying to use prisma do the work for me so that we don't have multiple queries going on (less efficient). Welcome any thoughts here.
I have two models, named users and messages. It's basically a chat application. The models are associated as below:
User.hasMany(Message);
Message.belongsTo(User);
User-> id, name, pic
Message-> id, text, timestamp, user_id (foreign key)
I want to get a list of users who has recently messaged. Here is what I've tried:
DB.User.findAll({
include: [{
model: DB.Message,
order: [
['timestamp', 'DESC']
],
limit: 1
}]
});
The SQL Query may look like this:
SELECT U.first_name, user_id, MAX(timestamp) FROM messages M, users
U WHERE M.user_id=U.id GROUP BY user_id
Try this
DB.User.findAll({
include: [ { model: DB.Message, required: true,order:['id','DESC']}]
});
I want to list out all of user ConversationData (ONE User HAS MANY CovnresationData), but i got 'undefined' when i followed tutorial on official site. Help, guys!
var User = db.define("user", {
name : String,
surname : String,
avatar : String,
username : String,
token : String
}, {
autoSave: true
});
var Conversation = db.define("conversations", {
name : Number,
createdAt : Date,
updatedAt : Date
});
var ConversationData = db.define("conversation_data", {
user_id : Number,
conversation_id : Number
});
db.sync();
User.hasMany('conversationsData', ConversationData, {}, {
autoFetch: true
});
User.find({id: 1}).first(function(err, asda) {
cconsole.log(asda.conversationsData);
});
OUTPUT:
(orm/postgres) SELECT "t1"."user_id", "t1"."conversation_id", "t1"."id" FROM "conversation_data" "t1" JOIN "user_conversationsData" "t2" ON "t2"."conversationsdata_id" = "t1"."id" WHERE "t2"."user_id" = 1
undefined
Request seems to me completely wrong. it must Join user and conversation data tables, as i understand..
At least as far as I've seen with MySQL, ORM handles hasMany relationships by creating a 'merge' table, in your case it is likely what you see as user_conversationsData. This table should have 3 columns, id (generated, ignore it), user_id to map to the Users table, and conversationdata_id to map to the conversationData table.
You have autofetch on, what ORM will do is fetch the User, and then fetch the conversationdata_id's and the conversationData's by joining the extra merge-table to the conversationData table. This is the query you see.
To access the conversationData, you should be able to see it as a property userInstance.conversationDatas. If that doesn't work, try calling console.dir(Object.keys(userInstance)) to see what's there.
I always have a certain fixed structure in my model (GroupName) and a dynamic part of 1-x (Members).
Group1
GroupName
Member 1
Member 2
Group2
GroupName
Member 1
Group3
GroupName
Member 1
Member 2
Member 3
Is it better to use two tables and connect them later via ids like this:
Groups:
Group1
GroupName
GroupId
Group2
GroupName
GroupId
Members:
Member 1
GroupId
Member 2
GroupId
or to use Schema.Types.Mixed(or anything else)? And how to do it in the second way?
I will always use them in combination later. From a gut feeling I would choose the first method:
http://blog.mongolab.com/2013/04/thinking-about-arrays-in-mongodb/
EDIT:
But even on the second method I have the issue, that one member can belong to multiple groups and I don't want to store him twice. The groups are unique and do only exist once.
But I'm new to MongoDb so I want to learn what's the best option and why.
EDIT II:
I have choosen two divide it into two docs. Is this implementation of the Schemas than correct like this:
var mongoose = require('mongoose');
// define the schema for group model
var groupSchema = mongoose.Schema({
href: {
type: String,
required: true,
unique: true
},
title: String,
members: [id: Schema.Types.ObjectId, name: String]
});
// create the model for users and expose it to our app
module.exports = mongoose.model('group', groupSchema);
&&
var mongoose = require('mongoose');
// define the schema for member model
var memberSchema = mongoose.Schema({
id: {
type:Schema.Types.ObjectId,
required: true,
unique: true
},
amount: String,
name: String
});
// create the model for users and expose it to our app
module.exports = mongoose.model('member', memberSchema);
There is an excellent post on the MongoDB blog which tells us about the various ways a schema can be designed based on the model relationships.
I believe the best schema for you would be to make use of embedded arrays with the member IDs.
//Group
{
_id: '1234',
name: 'some group',
members : [
'abcd',
'efgh'
]
}
EDIT
There is a correction needed in the schema:
// define the schema for group model
var groupSchema = mongoose.Schema({
href: {
type: String,
required: true,
unique: true
},
title: String,
members: [{id: Schema.Types.ObjectId, name: String}] //Needs to be enclosed with braces
});
// create the model for users and expose it to our app
module.exports = mongoose.model('group', groupSchema);
I don't know what your documents contains and if members are a growing array - for example Group1 can have 1-n members in any given moment . if this is the case you should go with option 2: try something like:
{gId: 1, mId: 5}
That is a design best suited for Social graph. Your Group documents will have a fixed size which is good for memory and you can easily get all the members of a group (just don't forget to index gId and mId)
If for each group there is a fixed number of members (or not growing and shrinking to much) then go with option 1
There is a great post by mongoDb team (and also src code) that talks about design.
Socialite
So the reason why im confused, because I am a PHP developer and used Laravel and FuelPHP alot
What i dont really understand is the association it self.
What i mean, i wanted to create a basic hasOne / BelongsTo logic, with the following
User has one profile
Profile belongs to an user
I am used to the following build up (Laravel style)
Users table
id | username | email | password
---------------------------------------
1 | My Username | My email | 1234568
Users_profile table
user_id | first_name | last_name
----------------------------------------
1 | My First name | My Last name
Then i just defined models this way
User model
class Users extends Eloquent
{
public function profile()
{
return $this->hasOne('profile');
}
}
Profile model
class Profile extends Eloquent
{
protected $tableName = 'users_profile';
protected $primaryKey = 'user_id';
public function user()
{
return $this->belongsTo('User');
}
}
And it just works, because the return $this->hasOne('profile'); will auto check for the user_id
Tried the same in Sails.js (in the sails way)
User model
module.exports = {
attributes: {
username: {
type: 'string',
unique: true,
required: true
},
email: {
type: 'string',
unique: true,
email: true,
required: true
},
password: {
type: 'string',
required: true
},
profile: {
model: "profile",
}
},
};
Profile model
module.exports = {
tableName: 'user_profile',
autoPK: false,
autoCreatedAt: false,
autoUpdateddAt: false,
attributes: {
user_id: {
type: 'integer',
primaryKey: true
},
first_name: {
type: 'string',
},
last_name: {
type: 'string',
},
user: {
model: "user"
}
}
};
And reading from the documentation now i have to update my table this way
id | username | email | password | profile
-------------------------------------------------
1 | My Username | My email | 1234568 | 1
user_id | first_name | last_name | user |
-----------------------------------------------
1 | My First name | My Last name | 1
So i need to store 2 more id's again, and i do not really get why.
Than i read further tried to use via did not work (noted that is for collections)
So, anybody could give me a logic example for a Laravelis style?
Foud nothing about this in the docs (a more easier way), because in my opinion if the user will have more relations, this will cause and ID hell (just my aopinion)
It is a known issue that Sails doesn't fully support one-to-one associations; you have to set the foreign key on whichever side you want to be able to populate from. That is, if you want to have User #1 linked to Profile #1 and be able to do User.find(1).populate('profile'), you would set the profile attribute of User #1, but that doesn't automatically mean that doing Profile.find(1).populate('user') will work. This is as opposed to many-to-many relationships in Sails, where adding the link on one side is sufficient. That's because to-many relationships use a join table, whereas to-one relationships do not.
The reason this hasn't been a priority in Sails is that one-to-one relationships are usually not really useful. Unless you have a really compelling reason for not doing so, you're better off just merging the two models into one.
In any case, if it's something you really need, you can use the .afterCreate lifecycle callback to ensure a bi-directional link, for example in User.js:
module.exports = {
attributes: {...},
afterCreate: function(values, cb) {
// If a profile ID was specified, or a profile was created
// along with the user...
if (values.profile) {
// Update the profile in question with the user's ID
return Profile.update({id: values.profile}, {user: values.id}).exec(cb);
}
// Otherwise just return
return cb();
}
};
You could add a similar .afterCreate() to Profile.js to handle updating the affected user when a profile was created.