2
votes

I have a tables called users, countries, and countries_users.

The documentation states that to delete a simple relationship you perform:

// Get user foo
$u = new User();
$u->where('username', 'foo')->get();

// Get country object for Australia
$c = new Country();
$c->where('name', 'Australia')->get();

// Delete relation between user foo and country Australia
$u->delete($c);

This would remove the corresponding row from the countries_users table.

My question is, what if I have no relevant Country() object to construct?

If countries and users are a one-to-many relationship, then certainly knowing the username attribute is enough to disassociate him with a country.

All the delete functions seem to require at least two objects... What is the best way to accomplish the deletion of this type of relation using the DataMapper ORM functions?

2
What did you mean by no relevant Country() and by knowing the username attribute? - Wesley Murch
1. I mean, I don't necessarily know the Country - nor should I need to know the country to make this relationship disassociation. 2. Whether username, or user_id... they are both unique keys for identifying a single record in the join table. - Jordan Arseno

2 Answers

3
votes

"All the delete functions seem to require at least two objects"

Not totally true, a delete() can be preformed on a single object without the need to explicitly delete the object's relationships, it is handled automatically.

From the user guide:

Note: When you delete an object, all its relations to other objects will also be deleted. Free house cleaning! :)

In addition, you may use a column in the users table for the country id instead of a separate countries_users table for relationships, assuming it is a one(country)-to-many(users) relationship.

My question is, what if I have no relevant Country() object to construct?

Then you don't have to worry about anything. If there are no relationships to delete, attempting to delete them will not cause any harm.

There is a relationship to delete! I want to pass the user_id into my Controller and disassociate him with a country in the countries_users table. To accomplish this using the documented functions, I would have to also pass in the country_id... Which IMO is irrelevant for this operation.

You don't have to look up the country id unless you specifically want to delete a particular relationship. In your case, you're working with a relationship where a user can only have one country, so you don't need to specify which related country to delete. Here are two options off the top of my head:

Assigning a new country (removes the previous one)

$c = new Country();
// Get all countries named "Wonderland"
// Usually we'll use an id instead, there could theoretically be more than one
$c->where('name', 'Wonderland')->get(); 
$user->save($c);

Just delete all related countries (there is only one of course)

$c = new Country();
// Get all countries
$c->get();
$user->delete($c); // You may need $c->all here

If we were working with a many to many relationship, you would of course have to know which ones to delete, but since there is only one - deleting them all is sufficient.

3
votes

Believe it or not, I was unable to remove the relationship using the code Wesley has provided.

However, this seemed to work:

$u = new User();
$u->where('id', $id)->include_related('country', 'id', TRUE, TRUE)->get();

$c = new Country();
$c->where('id', $u->country->id)->get();
$c->delete($u);