Let's use the TypeORM documentation's example of a many-to-many table:
#ManyToMany(type => Category)
#JoinTable({
name: "question_categories", // table name for the junction table of this relation
joinColumn: {
name: "question",
referencedColumnName: "id"
},
inverseJoinColumn: {
name: "category",
referencedColumnName: "id"
}
})
categories: Category[];
Let's say I want to query directly against this table to run something like select * from question_categories where category = 3;. How do I express this with TypeORM's query builder? The table doesn't correspond to an entity so I don't know how to refer to it with the query builder API. Do I need to use entityManager.query for this?
I ended up creating a new entity for the junction table and querying directly against it that way.
Related
I want to implement a few simple models to my ruby on rails project. I have the model hierarchy, Topic and Project. A Topic will contain many Projects. I wanted to know what the difference was between adding a "has_many projects" relation in the Topic model vs just adding an array field in the Topic model that stores all of the projects within it.
I am using Ruby on Rails with mongodb as my database and mongoid as the object document mapper.
Let's say in you're Topic model:
has_many :projects
Now, if you query like, #project.topic will execute a single query.
Let's say, you add a column in topic which stores project_ids, e.g.: [1,2,3]
Now if you want to find any individual #topic projects you need to do like this:
first, fetch the #topic.project_ids
Then, for each id query to the Project table, if array contains 3 values then 3 query will run.
So, all is about execution time.
Array Store
you can use to take reference ids of child association. eg
users:
[
{
_id: ObjectId('oii3213ui23uo')
name: 'John',
email: 'jhn#example.com',
project_ids: ['oii3213ui23u1', 'oii3213ui23uo2' ,'oii3213ui23uo3']
}
]
projects:
[
{
_id: ObjectId('oii3213ui23u1'),
title: 'Project 1'
},
{
_id: ObjectId('oii3213ui23u2'),
title: 'Project 2'
},
{
_id: ObjectId('oii3213ui23u3'),
title: 'Project 3'
}
]
has_many
You can use to embed child associations in parent document. eg
users:
[
{
_id: ObjectId('oii3213ui23uo')
name: 'John',
email: 'jhn#example.com',
projects: [
{
title: 'Project 1'
},
{
title: 'Project 2'
},
{
title: 'Project 3'
}
]
}
]
I have simple schema with one-to-one relation:
Site:
columns:
name: { type: string(255) }
User:
columns:
name: { type: string(255) }
site_id: { type: integer }
relations:
Site: { foreignType: one }
I am overriding Site::save() method (which is called when I edit Site from admin generator), where I need to do smth with User, and User references Site again:
echo $this->getUser()->getSite()->getName();
When getSite() is called, $this is overwritten by values from database, because Doctrine loads "Site" relation from db and replaces $this according to identity map. Obviously, all changes to object are lost. After some code reading i got that User object does not have _references['Site'] set after getUser(), that's why Doctrine tries to load Site from db. If i prepend
$this->getUser()->setSite($this);
, then everything works as expected and no additional queries are made. Another workaround is to join relations in query:
$this->site = Doctrine::getTable('Site')
->createQuery('s')
->leftJoin('s.User u')
->leftJoin('u.Site us')
->fetchOne();
But is that an intended behaviour? How can I make Doctrine know that $this === $this->getUser()->getSite()? I use symfony 1.4.18 with Doctrine 1.2.4. Thank you.
I'm using symfony for a project but got stuck at one point building the schema. In the schema I have one table user that can be created by himself or and administrator and the user ids are stored in sfGuardUser... how can y make a relation between them in the schema.yml?
I have this fields:
tableX
sf_guard_user_id: {type: integer}
sf_guard_user_id_cs: {type: integer}
The first id is the one he gets when created and the second is the administrator's id if it was created by one. So basically, I'm gonna use the id field from sfGuardUser twice in tableX but I'm not able to make this two relations in the schema.yml. Anyone knows how to do the relations?
It is simple. For example:
CoolTable:
actAs:
Timestampable: ~
columns:
sf_guard_user_id: { type: integer() }
sf_guard_user_id_cs: { type: integer() }
relations:
User: { local: sf_guard_user_id, foreign: id, class: sfGuardUser }
UserCs: { local: sf_guard_user_id_cs, foreign: id, class: sfGuardUser }
Main point, that you specify the class of relations.
I can't get the onDelete to work in Doctrine2 (with YAML Mapping).
I tried this relation in my Product class:
oneToOne:
category:
targetEntity: Category
onDelete: CASCADE
But that doesn't work..
EDIT:
I've set the ON DELETE: CASCADE manually in the database
imported the YAML mapping with doctrine:mapping:import,
emptied the database
updated it from the schema with doctrine:schema:update and got no ON DELETE in the foreign key.. so looks like even Doctrine doesn't know how to do it lol..
OK, got it! I had to use onDelete inside joinColumn:
oneToOne:
category:
targetEntity: Category
joinColumn:
onDelete: CASCADE
This is the way to use onDelete in joinTable:
manyToMany:
parameters:
targetEntity: Fox\LandingBundle\Entity\Parameter
cascade: ["persist","remove"]
joinTable:
name: subscriberBox_parameter
joinColumns:
subscriberBox_id:
referencedColumnName: id
inverseJoinColumns:
parameter_id:
referencedColumnName: id
onDelete: CASCADE
I'm relatively new to Mongoid/MongoDB and I have a question about how to model a specific many-to-many relationship.
I have a User model and a Project model. Users can belong to many projects, and each project membership includes one role (eg. "administrator", "editor", or "viewer"). If I were using ActiveRecord then I'd set up a many-to-many association between User and Project using has_many :through and then I'd put a field for role in the join table.
What is a good way to model this scenario in MongoDB and how would I declare that model with Mongoid? The example below seems like a good way to model this, but I don't know how to elegantly declare the relational association between User and the embedded ProjectMembership with Mongoid.
Thanks in advance!
db.projects.insert(
{
"name" : "Test project",
"memberships" : [
{
"user_id" : ObjectId("4d730fcfcedc351d67000002"),
"role" : "administrator"
},
{
"role" : "editor",
"user_id" : ObjectId("4d731fe3cedc351fa7000002")
}
]
}
)
db.projects.ensureIndex({"memberships.user_id": 1})
Modeling a good Mongodb schema really depends on how you access your data. In your described case, you will index your memberships.user_id key which seems ok. But your document size will grow as you will add viewers, editors and administrators. Also, your schema will make it difficult to make querys like:
Query projects, where user_id xxx is editor:
Again, you maybe do not need to query projects like this, so your schema looks fine. But if you need to query your projects by user_id AND role, i would recommend you creating a 'project_membership' collection :
db.project_memberships.insert(
{
"project_id" : ObjectId("4d730fcfcedc351d67000032"),
"editors" : [
ObjectId("4d730fcfcedc351d67000002"),
ObjectId("4d730fcfcedc351d67000004")
],
"viewers" : [
ObjectId("4d730fcfcedc351d67000002"),
ObjectId("4d730fcfcedc351d67000004"),
ObjectId("4d730fcfcedc351d67000001"),
ObjectId("4d730fcfcedc351d67000005")
],
"administrator" : [
ObjectId("4d730fcfcedc351d67000011"),
ObjectId("4d730fcfcedc351d67000012")
]
}
)
db.project_memberships.ensureIndex({"editors": 1})
db.project_memberships.ensureIndex({"viewers": 1})
db.project_memberships.ensureIndex({"administrator": 1})
Or even easier... add an index on your project schema:
db.projects.ensureIndex({"memberships.role": 1})