pop icon indicating copy to clipboard operation
pop copied to clipboard

[Question] best way to use many_to_many

Open badstorm opened this issue 6 years ago • 2 comments

Description

Hi, i'm trying to implement a many_to_many relation on my models. But I don't understand how I can update the relations.

Steps to Reproduce the Problem

Following the documentation, I have this models:

type User struct {
   ID   uuid.UUID `json:"id" db:"id"`
   ...
}

type Group struct {
   ID   uuid.UUID `json:"id" db:"id"`
   ...
   Users   Users `many_to_many:"groups_users"`
}

Then i create the table groups_users

create_table("groups_users") {
	t.Column("id", "uuid", {primary: true})
	t.Column("group_id", "uuid", {})
	t.Column("user_id", "uuid", {})
	t.Timestamps()
}

Now, when I create a new group, I add a multi select on the HTML form with the list of users. <%= f.SelectTag("Users", {options: users, multiple: true}) %>

Expected Behavior

My intent is to keep updated the relations when create/update a group item.

Actual Behavior

Running the project with this settings, nothing appens. The groups_users keep empty. I try add Eager() to the ValidateCreate method. But nothig.

So I add a new field to group used in the form: UsersFrom []uuid.UUID json:"-" db:"-"`` I updated the html form <%= f.SelectTag("UsersFrom", {options: users, multiple: true}) %> And i add this code:

for _,u := range group.UsersFrom {
   user := &models.User{}
   if err := tx.Find(user, u); err != nil {
      return c.Error(404, err)
   }
    group.Users = append(group.Users, *user)
}

And now when i create a new group i get the releations.

But if i add the same to the Update method, it never update the relations.

Which is the best way to use many_to_many?

Info

Buffalo version is: v0.14.10
pop v4.11.6

badstorm avatar Sep 07 '19 14:09 badstorm

Thanks for the great lib and I can confirm I am running into the same issue as well with a very similar model. There doesn't seem to be a clean association when using a many_to_many when following the documentation to create the join. A many_to_one is working great but many_to_many will create the relationship objects but then silently fails to associate them. That happens with .Eager().Update or .Eager.Create()

ie:

content.Tags = [Tag{Name: A}, Tag{Name: B}] tx.Eager().Create(&content)

And it DOES definitely create the objects but maybe my join is just misnamed?

content_test=# select id, src, content_type from contents;
                  id                  | src | content_type
--------------------------------------+-----+--------------
 851f8301-22b5-4d9a-ba09-36b90c2dc9b6 | A   | video
(1 row)

content_test=# select * from contents_tags;
 id | content_id | tag_id | created_at | updated_at
----+------------+--------+------------+------------
(0 rows)

content_test=# select * from tags;
                  id                  | name |         created_at         |         updated_at
--------------------------------------+------+----------------------------+----------------------------
 7dd3b3c1-4cea-46fd-8482-9e02ca73f36e | A    | 2022-10-12 15:16:00.711353 | 2022-10-12 15:16:00.711353
 11ab0e55-498a-4c0f-b36a-e787cea40d39 | B    | 2022-10-12 15:16:00.715139 | 2022-10-12 15:16:00.715139

UberMeatShield avatar Oct 12 '22 19:10 UberMeatShield

Hi @UberMeatShield,

Thank you for adding additional information here! I have a plan to revisit this issue later (as a milestone v6.3.0 currently) but have not enough bandwidth for now. Sorry for that, will check the issue as soon as possible!

Currently, there could be some issues with Eager actions. The current workaround could be adding the relationship entries with a separate Creation.

sio4 avatar Oct 15 '22 09:10 sio4