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

Dump fields using Ecto when serializing changes #83

Merged
merged 9 commits into from
Nov 28, 2020

Conversation

rschef
Copy link
Contributor

@rschef rschef commented May 1, 2020

  • Dump fields using Ecto when serializing changes

Ecto.embedded_dump/2 is now called when serializing changes, which means custom Ecto fields have their dump/1 callback called if their callback embed_as/1 return :dump (default is :self).

These changes were done only in this commit: nash-io@1c97a58

  • Fixed test/paper_trail/base_tests.exs file not being run, because it didn't end with the sufix _test.exs

  • Created PaperTrail.Serializer module and reused it across the application

The following functions were being declared in multiple modules, although they had the same implementation.

Now all modules delegate to the PaperTrail.Serializer module:

  defdelegate make_version_struct(version, model, options), to: Serializer
  defdelegate get_sequence_from_model(changeset), to: Serializer
  defdelegate serialize(data), to: Serializer
  defdelegate get_sequence_id(table_name), to: Serializer
  defdelegate add_prefix(changeset, prefix), to: Serializer
  defdelegate get_item_type(data), to: Serializer
  defdelegate get_model_id(model), to: Serializer

@izelnakri
Copy link
Owner

Hi @rschef, I'll review this PR soon. Thanks for submitting it!

@@ -978,11 +993,6 @@ defmodule PaperTrailTest.SimpleModeBangFunctions do
first(Person, :id) |> MultiTenant.add_prefix_to_query() |> repo().one()
end

defp serialize(model) do
Copy link
Owner

Choose a reason for hiding this comment

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

This made me like the PaperTrail.Serializer module even more, thank you. I'll read up on Ecto.embedded_dump

@@ -1,3 +1,32 @@

defmodule LocationType do
Copy link
Owner

Choose a reason for hiding this comment

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

This is also very interesting, thanks for adding it to the tests.

@izelnakri
Copy link
Owner

I'll read up on Ecto.embedded_dump and run the tests locally before merging to master. Thanks again for contributing @rschef !

def add_prefix(changeset, prefix), do: Ecto.put_meta(changeset, prefix: prefix)

def get_item_type(%Ecto.Changeset{data: data}), do: get_item_type(data)
def get_item_type(%schema{}), do: schema |> Module.split() |> List.last()
Copy link
Owner

Choose a reason for hiding this comment

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

interesting trying this out now.

Copy link
Owner

Choose a reason for hiding this comment

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

ok verified that behavior is exactly the same and all tests passing

@izelnakri
Copy link
Owner

izelnakri commented May 5, 2020

@rschef all looks good to me thank you. I have one final request, since now serializer methods are public could you also add the doc strings/documentation to those as well? Then we can merge and release it the same day, thanks!

@rschef
Copy link
Contributor Author

rschef commented May 6, 2020

Hi @izelnakri, thanks for the feedback and taking the time to review this PR.

Unfortunately I'm short on time this week, so I'll only be able to address your request over the weekend.

@izelnakri
Copy link
Owner

Hi @rschef, I see more feature requests coming up. Could you finalize the PR sometime these days? Then we can merge can cut a release, thanks!

@rschef
Copy link
Contributor Author

rschef commented Jun 27, 2020

@izelnakri Sorry for only replying to you now, these have been busy weeks. Yes, I plan to submit other 3 feature requests after this one is merged:

But back to this PR, I found troublesome having to define a embed_as/1 function for every Ecto type, since a lot of times they are created internally by other packages or applications and it's easy to forget it. So I decided to dump all schema fields and do it the same way Ecto does when dumping to the database. I tried to find a public function that I could call in Ecto to dump a struct created by an Ecto schema, but unfortunately, they were all private functions. So I ended up copying them here.

With that, I solved that issue, but created another one. Some Ecto types, such as Ecto.UUID, convert from string to binary when dumping a field and, therefore, Jason failed to encode it to json. So my solution was to add a configuration that allowed to skip some Ecto.Types, which was implemented here.

If you agree with those decisions and solutions, I can work on this PR to implement them. Otherwise, if you have other suggestions for those issues, please let me know.

@izelnakri
Copy link
Owner

Hi @rschef I just saw your response, sorry for replying late!

This PR is pretty much done, I would just need documentation on the public methods. Please let me know when thats done, then we can merge it.

Also I checked the links you've shared, seems like they have been merged to nash fork already. I think it would be better for everyone if we keep one version of paper_trail for everyone including for nash, I understand nash might be using a fork for rapid development internally. I'm willing to review all open PRs to this repository.

@rschef
Copy link
Contributor Author

rschef commented Jul 9, 2020

Hi @izelnakri, thanks for your reply.

Sure, I agree with you about having only one version of paper_trail. I'll do my best to open those PRs in this repository after this one is merged.

I'll add the missing documentation as soon as I have some time and then I can open a new PR later to implement the changes I mentioned here

@rschef rschef requested a review from izelnakri July 18, 2020 17:21
@rschef
Copy link
Contributor Author

rschef commented Jul 18, 2020

Added type specs and docs to Serializer, @izelnakri please take one more look

Dumps changes using Ecto fields
"""
@spec serialize_changes(Ecto.Changeset.t()) :: map()
def serialize_changes(%Ecto.Changeset{data: %schema{}, changes: changes}) do
Copy link
Owner

@izelnakri izelnakri Jul 19, 2020

Choose a reason for hiding this comment

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

@rschef what was the reason of having this public method instead of just having serialize()? Was there a performance issue previously?

@izelnakri
Copy link
Owner

Hi @rschef, thanks for adding the documentation! I have only one question and a minor documentation suggestion. Then we can merge it!

@izelnakri
Copy link
Owner

Hi @rschef, could you rebase from master? There were few MRs merged prior, we'll need to rebase and adjust these changes. Thanks

@izelnakri izelnakri force-pushed the master branch 2 times, most recently from a06c813 to 675d502 Compare October 1, 2020 20:42
@rschef
Copy link
Contributor Author

rschef commented Oct 2, 2020

Hi @izelnakri, I've rebased from master :)

@izelnakri izelnakri mentioned this pull request Oct 15, 2020
1 task
@izelnakri izelnakri merged commit 88dc4b2 into izelnakri:master Nov 28, 2020
mayel pushed a commit to bonfire-networks/paper_trail that referenced this pull request Jun 26, 2023
* Add .tool-versions to .gitignore

* Change logger level to warn in test environment

* Fix warning when running tests

* Create serializer module and reuse it across the application

* Dump ecto fields when serializing changes

* Add type specs and docs to Serializer

* Replace get_sequence_from_model/1 by get_sequence_id/1

* Apply documentation
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.

2 participants