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

Related relations #257

Closed
wants to merge 6 commits into from
Closed

Related relations #257

wants to merge 6 commits into from

Conversation

jschlies
Copy link

@jschlies jschlies commented Jun 25, 2017

This pull request is my initial attempt to audit the relationships of a particular model. Please comment but I am unwilling to push this intil I deal with the 3 Todo's.

Be warned: This can have negative impact on DB performance. Be very cautious to not use this feature on too many models (and those models relationships). This PR offers controls on both.

Todo:
Create table related_relations and use this rather that audits:related_relation_json
Integrate this into $model->audits()
Better unit tests

Todo (far future)
Make this Event/Queue friendly to try to deal w/ the DB load this this can generate.

To use:

Run the migration adding related_relation_json to audits table

All models for which you want to track related_relations need:

  1. A public property of $model->auditIncludeRelated set to true
  2. These public methods: $model->getBelongsToArr(), $model->HasManyArr,$model->GetBelongsToManyArr(), $model->getHasOneArr(). These should return an array of strings that indicate the names of the Eloquent properties (relations) you wish to track.
  3. If you are auditing the related models of $a (say $b and $c), you minimally need to audit $b and $c.

$related_relations_arr = [];
$broad_relationship_types_arr = ['BelongsTo', 'HasMany', 'BelongsToMany', 'HasOne'];

if ( ! $this->auditIncludeRelated)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Expected 0 spaces after opening bracket; 1 found
  • Expected 1 space after closing parenthesis; found 9

{
return $related_relations_arr;
}
foreach ($broad_relationship_types_arr as $broad_relationship)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expected 1 space after closing parenthesis; found 9

return $related_relations_arr;
}
foreach ($broad_relationship_types_arr as $broad_relationship)
{

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expected 1 newline after opening brace; 2 found

{

$broad_relationship_method = 'get'.ucfirst($broad_relationship) . 'Arr';
if ( ! method_exists($this, $broad_relationship_method))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Expected 0 spaces after opening bracket; 1 found
  • Expected 1 space after closing parenthesis; found 13

}
$related_relations_arr[$broad_relationship] = [];
$relationship_arr = $this->$broad_relationship_method();
foreach ($relationship_arr as $relationship)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expected 1 space after closing parenthesis; found 13

$relationship_arr = $this->$broad_relationship_method();
foreach ($relationship_arr as $relationship)
{
if ( ! method_exists($this, $relationship))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Expected 0 spaces after opening bracket; 1 found
  • Expected 1 space after closing parenthesis; found 17

continue;
}
$RelationshipObjArr = $this->$relationship;
if ( ! is_iterable($RelationshipObjArr))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Expected 0 spaces after opening bracket; 1 found
  • Expected 1 space after closing parenthesis; found 17

{
$RelationshipObjArr = [$RelationshipObjArr];
}
foreach ($RelationshipObjArr as $RelationshipObj)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expected 1 space after closing parenthesis; found 17

'source_relation' => get_class($this),
'source_relation_id' => $this->{$this->primaryKey},
];
if($RelationshipObj == null)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Expected 1 space after IF keyword; 0 found
  • Expected 1 space after closing parenthesis; found 21

* this can happen when a foreign key constraint referances the self-same table.
*/
$x=1;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expected 1 space after closing brace; newline found

*/
$x=1;
}
else

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expected 1 space after ELSE keyword; newline found

$related_relations_arr = [];
$broad_relationship_types_arr = ['BelongsTo', 'HasMany', 'BelongsToMany', 'HasOne'];

if (! property_exists($this,'auditIncludeRelated') || ! $this->auditIncludeRelated)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • No space found after comma in function call
  • Expected 1 space after closing parenthesis; found 9

/**
* this can happen when a foreign key constraint referances the self-same table.
*/
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expected 1 space after closing brace; newline found

* this can happen when a foreign key constraint referances the self-same table.
*/
}
else

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expected 1 space after ELSE keyword; newline found

@quetzyg
Copy link
Contributor

quetzyg commented Jun 25, 2017

Hi @jschlies,

Thanks for trying to come up with a solution to the many-to-many relation auditing.

On your TODO, you state that there should be a related_relations table, instead of a new audits column (related_relation_json in this case), why so?

Also, the logic you're proposing is using relation types (BelongsTo, and so on) instead of events, why?

And how do you deal with a sync() call that would remove/add lots of relations? Would you create an audit record for each, or do you create a single one with all the changes?

@jschlies
Copy link
Author

@quetzyg

On your TODO, you state that there should be a related_relations table, instead of a new audits column (related_relation_json in this case), why so?

It would be extremely hard to extract the data needed to run $somethingRelatedToodel->audits() for not only the object in question but it's relations. As I stated above, this fix runs the risk of overloading the DB w/ insert requests. Perhaps there is a way to bundle these inserts or get them offline somehow.

Also, the logic you're proposing is using relation types (BelongsTo, and so on) instead of events, why?

This is our current implementation and it serves us well. I will explore using events as you indicate. Can you point me in a direction on this?

And how do you deal with a sync() call that would remove/add lots of relations? Would you create an audit record for each, or do you create a single one with all the changes?

I don't but if I did, (and I will research doing so), each relationship would get it's own related_relation record. As I stated above, this fix runs the risk of overloading the DB w/ insert requests. Perhaps there is a way to bundle these inserts or get them offline somehow.

-=-=-=-=-=-=-
Thanks for the input and will explore the issues you point out. Keep the comments coming

@jschlies
Copy link
Author

jschlies commented Jun 25, 2017

AuditableTrait.php.txt

See attached for our current implementation of $this->getAuditArr(). Ignore the sorting stuff.

@quetzyg
Copy link
Contributor

quetzyg commented Jun 25, 2017

This is our current implementation and it serves us well. I will explore using events as you indicate. Can you point me in a direction on this?

In regards to the usage of events, I commented in the open issue #58. The idea would be to fire an event from a repository and that would kickstart the audit process.

@quetzyg
Copy link
Contributor

quetzyg commented Jun 25, 2017

You totally lost me with the AuditableTrait.php.txt

@jschlies
Copy link
Author

I think that a great idea (events and potentially queuing) and will implement but I think that a separate topic to be taken up later.

@jschlies
Copy link
Author

AuditableTrait.php.txt contains our implementation of getAuditArr().
Can you elaborate?

@quetzyg
Copy link
Contributor

quetzyg commented Jun 25, 2017

The code, is confusing.

@jschlies
Copy link
Author

I'll spend some time commenting.
Keep in mind:

  • The table I propose, related_relations, is called audit_relations in our implementation.
  • $generations keeps our use of recursion under control.
  • If you think of a beter nomenclature than 'source' and 'related', please let me know.
  • In our implementation, we only really care about belongsTo.
  • ignore the sorting stuff

@quetzyg
Copy link
Contributor

quetzyg commented Jul 2, 2017

Closing it, since we're currently working on version 4.1.

@quetzyg quetzyg closed this Jul 2, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants