Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create many to many instance with id? #1241

Closed
seanchenca opened this issue Nov 26, 2017 · 4 comments
Closed

Create many to many instance with id? #1241

seanchenca opened this issue Nov 26, 2017 · 4 comments
Labels

Comments

@seanchenca
Copy link

Hi,

Let say I have two classes:

@Entity('resource')
class Resource extends EntBase {

  @Column({ type: 'varchar', length: 64 })
  title: string

  @ManyToMany(type => Topic, topic => topic.resources)
  @JoinTable({ name: 'resource_topic' })
  topics: Topic[]
}

@Entity('topic')
class Topic extends EntBase {

  @Column({ type: 'varchar', length: 64 })
  topic: string

  @ManyToMany(type => Resource, resource => resource.topics)
  resources: Resource[]
}

and I would like to create a new Resource with two topics, and I already know the ids of the two topic (suppose they are 1, and 2), I am assuming I have to do:

const topic1 = awiat topicRepo.findById(1);
resource.topics.push(topic1);
const topic2 = await topicRepo.findById(2);
resource.topics.push(topic2);
resourceRepo.create(resource);

is it possible to save the Resource without creating instances of Topic? or do I have to manipulate the 'resource_topic' table manually?

btw, if I omit the {type: 'varchar', length: 64} for the topic column and leave it just:

@Column()
topic: string

I got an error:

sqlMessage: 'You have an error in your SQL syntax; check the manual that corresponds to yourMySQL server version for the right syntax to use near \'NOT NULL, `lang` enum(\'en\', \'fr\') NOT NULL) ENGINE=InnoDB\' at line 1',
[Node]   sqlState: '42000',
[Node]   index: 0,
[Node]   sql: 'CREATE TABLE `topic` (`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT, `createdAt` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), `updatedAt` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), `version` int(11) NOT NULL, `topic`  NOT NULL, `lang` enum(\'en\', \'fr\') NOT NULL) ENGINE=InnoDB',

looks like the query is not specifying type of topic, I thought typeorm is going to infer that from the string type and make it varchar(255), am I missing some settings?

@pleerock
Copy link
Member

Regarding to your question - checkout how to work with relational query builder.

Regarding to your error - did you specify a reflect-metadata properly? Looks like it cannot get type reflection from your properties.

@seanchenca
Copy link
Author

thanks @pleerock for pointing out the doc. works perfectly:

      .createQueryBuilder()
      .relation(Resource, 'topics')
      .of(resourceId)
      .addAndRemove([...], [...])

for the error, do you refer to the option in tsconfig.json?:

"emitDecoratorMetadata": true,

I do have this option enabled, or is it something else?

@seanchenca
Copy link
Author

seanchenca commented Nov 28, 2017

hi @pleerock, seems I have some problem with the addAndRemove call. let say originally I have two resources id 1 and 2. resource 1 has topics id 1 and 2, resource 2 has no topic. so the resource_topic table has the following record:

resourceId  |  topicId
----------------------
       1    |      1
       1    |      2

now I want to update resource 2 to have topics id 3 and 4, after I call:

getConnection()
      .createQueryBuilder()
      .relation(Resource, 'topics')
      .of(2)
      .addAndRemove([3, 4], []);

the resource_topic table become:

resourceId  |  topicId
----------------------
       2    |      3
       2    |      4

i.e. the record for resource id 1 are wiped out. the reason I use addAndRemove and passing an empty array for removing ids is because if there were topics associated with resource I would like to remove the original ones

also if I call

getConnection()
      .createQueryBuilder()
      .relation(Resource, 'topics')
      .of(2)
      .addAndRemove([], []);

or

getConnection()
      .createQueryBuilder()
      .relation(Resource, 'topics')
      .of(2)
      .remove([]);

the whole resource_topic table is wiped out and become completely empty too.

could you see what I did wrong here?

@pleerock
Copy link
Member

Its not expected behaviour. If you send empty array it should not do anything. Fixed and will be released in 0.1.7

pleerock pushed a commit that referenced this issue Dec 1, 2017
* master:
  fixed tslint error
  removed only test
  fixes #1270
  webpack: enable usage in node projects by not automatically selecting browser version
  updated changelog
  fixes #1241
  driver(cordova): support extra options
  remove only
  added tests for #1261
  fixes #1259
  fixes #1259
  fixes #1254; version bump
  fixes #1254

# Conflicts:
#	CHANGELOG.md
#	package.json
#	src/entity-manager/EntityManager.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants