Build a diff checker with database record version control #169

22/05/2024
Transcript
Hello friends. Today we're going to build a text comparison tool where you're going to be able to have two different texts and compare the differences between them. Here is a simple example, so just a random online tool where I inputted one version of the text, inputted another version of the text. And by clicking check the difference, we see the difference between the two versions. This is especially useful when you have different versions of contracts that you are about to sign. Now, for me, as a programmer, the most, uh, common, uh, uh, tool for viewing diffs between different, uh, texts or different files is, uh, obviously gi. So here I'm looking at GitHub, just a random comment, and I see different files that have been changed, and I see the differences between the, the current version and the previous version. There is this unified view by default, and there is also that split, uh, view where I see side by side the changes in the previous file and in the new file. And in this specific application, they're going to have, uh, a list of posts. A post has a title and the body. And, uh, I will be able to try the changes in the title and the body. So they're going to, uh, track the changes of, uh, attributes and they're going to display the d between the, the previous version and the new version. So if I added the title, I will be able to see versions like the, the previous version of the title, the new version, and the diff. And same with body. Now, how can we do this? First of all, we're going to install the gem audited. That will let us, uh, track the diffs. So gem audited. Here it is. So, uh, I'm going to add to the gem file, or I can just, uh, run bundle, add audited. And next I'm going to run rails, generate audited install. It'll run a migration. Let's have a look at the migration. Install, audited. So it creates a new table where we have audits. So we can audit a post or a user or any kind of a model in our application. Then we can, uh, store the user that, uh, did the change. We can, uh, see the difference of the changes. This is the most important attribute. 'cause here we're going to store the old title and new title, the old body and the new body, the versions. So initially the version is zero. Then, uh, it increments by one and possibly additional comments, uh, and, uh, like AP address of the, uh, person that, uh, or of the machine that made the change. Okay, so here we have the migration. Let's run rails, the B migrate. And now I will go to the post model and I will add audited. Now, uh, if you look at the documentation of the audited gem, you can specify that you want to audit only specific, uh, columns, or you want to audit, uh, only when the, uh, there is a great action, but not when there is an update Action, for example. Or you can require comments, uh, comments, or you can, uh, store for example, only two or only five audits per like, only the latest, uh, few audits per, uh, post. For example, a post has like 10,000, uh, changes and you don't want to store all of them. Uh, in our case, let's just audit everything. They're going to audit both the title and the, the body changes of a post. Okay, uh, let's see if, uh, this works. I will, uh, start the rails, uh, uh, server. I will, uh, uh, open this post. I will edit this post. So let's change it like PWA to, uh, no, let's change rails. Eight to rails nine will, uh, maybe be a PWA or let's change the web to the internet update post. So I have saved the post, and let's have a look at the audits of this post. I will open the Rails console post first audits. So here we have an audit. Let's count the audit. There is one audit, uh, and in the audit we have, uh, so the polymorphic association with the post, we don't have a current user. So that's, uh, obvious that it is new. Uh, the action was update because we already had it created. And here are the audited changes. So the old title and the new title, the Old body and the, the New Body. And based on this, later on, we are going to display the diff. We also see the version is fun. There is no comment, and we see the information about the IP and the request ID of this change. Okay, looks good. Let's, uh, display the change history in the view. I will study rail server. So inside the post show, I will also display the audit history, the change history post slash show. So let's put a break, a header, uh, audits. And, uh, we will count the audits. I will say at post audits dot count. So there is just one change at the moment. Now let's, uh, display all the changes. So I will say post audits, do each do audit and here equals audit. So yeah, we have an audit at the moment. Let's, uh, put it in a separate, uh, div to make it more visually different. So div and, uh, we have audit. What attribute does the audit have? It has created at, it has version, it has action. So this is when it happened. The version was fun, and the action was an update. And, uh, we will also have audited changes. So here is the hash of audit that changes the title and the body. Let's, um, now, uh, uh, try creating a new post. Let's, uh, create a new post, new post with body create post. So there is just one audit. The action was create. Here's the title and the body. There is, uh, no hash here. Let's compare. So here we have, uh, yeah, he have, have an array of, uh, two different versions. And, uh, here we don't have an array. We just have a stream because there is no previous version. Okay, so, uh, now we already track, uh, the changes in both title and, uh, body. And we want to display the diff as does, uh, GitHub here, as does this, uh, random diff jacket tool. Uh, here. How can we do this? Actually, there exists a great Ruby gem, GEM dfi, and the gem is going to do all the heavy lifting of, uh, uh, creating the diff between the strings and, uh, uh, making our HTML markup look good. So let's install the gem dfi. I will, again go back here and say bundle add dfi, okay, rail server. And let's see how we can use this jam. So, uh, we can put, we can display the diff between, uh, two strings. So string number one and string number two. Let's, uh, try using this. So, uh, here have, uh, yeah, let's try with this one. But we have two different versions, uh, inside the array, version one and version two. So, um, inside the audit, the changes we will have, uh, uh, each do, uh, attribute. The attributes are body and title and changes. The changes are version one and version two, attribute and changes. Okay, let's display the attribute equals attribute and, uh, equals changes. Let's also put this into a separative. Okay, so we have the attribute and the two changes, the attribute and the, the array better. Two elements, the old version and the new version. So, uh, uh, to have string one and string two, we'll have changes, uh, element one in the array and, uh, changes element two in the array. So, um, let's have, uh, definitive new changes. The first element, so with index zero and changes one, let's not display these changes anymore. And let's close this, uh, here. B tag. Um, yeah, okay. So here we have some kind of H TM L generated, but it doesn't display as h TM L in our application. We need to say HTML save. Okay, so we have the old version and new version, old version and new version. But it looks, uh, quite ugly to make it look good. We will need to go back to the docs of, uh, uh, dfi and, uh, go with the DCSS. So we can, uh, uh, yeah, just copy the CSS and put it into our, uh, application. Do CSS file. Let's, uh, refresh and it'll really looks much better. So we have version one and version two, but the text, uh, changes themselves are not highlighted, just the changes in the rows. So instead of using this html simple, we'll just use html. Okay? So this looks much better. And we can also, uh, add some additional options as, uh, include, uh, plus, uh, and minus in, uh, H TM L two. Okay. Looks even better now. Um, mm-Hmm. And, uh, yeah, looks fine. So we see the difference in the changes of the title and, uh, the body. Uh, now let's see if it works for the other attribute. Oh, not for the other attribute, but in case of, uh, uh, not having an array. You see it doesn't work because, uh, have, you just have a string. You have have an array, two different areas that we compare and show the differences. And here, there is no error to compare it. So I'm going to say, um, if, uh, the changes is an error, then they're going to display this. So if, um, changes is, uh, array, they're going to display this diff else, they're going to compare with, uh, an an empty initial version. So here you see, uh, yeah, we don't need also this, uh, we're having the full string compared to nothing. So here we see that that was created the out of nothing, a title, new post, and, uh, a body with Body. Let's edit this. I will, uh, with a sex body, uh, new edited post. And here we have two different versions. So looks, uh, good have, have vision one and version two, but I imagine it would be more useful to have the latest version on top. Uh, so let's change the order. I will try saying order version, the send in. Okay, nothing changed. Let's make version ascend in. Nothing changed. Uh, maybe they'll have to use, not order, but uh, sought by version dot reverse. Okay, now we have the latest version, uh, and the changes from the latest version on top. So, okay, now we can try the changes of the title and the body. Let's say they change only the title without changing the body. So, uh, you see in the latest version, we don't even log the change of the body because nothing changed and we see a difference in the title. So, uh, looks, uh, quite good. Now, uh, let's also, uh, have a look at GitHub. Here we have this, uh, unified view that we already kind of implemented. Instead of having different files, we have different attributes of the post. And, uh, let's also implement this split view. And DFI can also help us with this. Div has the option of, uh, DFI split Diff, and they're going to have the left column and right column. So let's implement this. And we're going to also add a toggle between the split and unified views. So let's first add the toggle. I will say, uh, if Rams, uh, split to s equals true, I will have a link to, uh, uh, column view or unified view, uh, post path at post. Uh, otherwise I'm going to have the link to post path, but I'm going to say split equals true. So, uh, let's see if the toggle works. We have the column, okay, it doesn't work. Um, uh, why doesn't it work? So, uh, this will be split. Um, okay, something isn't f let's see. So if per split equals through, we'll have column view. Uh, otherwise we'll have split view. Uh, what is the URL here? It makes sense. Okay, yeah. Now it is broken. Strange, maybe I just didn't refresh the page correctly. So the ULS change and let's have, uh, the conditional difference here. So, uh, I will say, uh, if PERS split to S equals true, then they're going to have the split view. Uh, otherwise they're going to have the normal view, the column view, and let's, uh, add the split view. So I'm going to have this DFI left and diffy right equals dfi left and dfi right. And here will have changes. Zero and changes one. Let's see if this works. So, uh, I go to the split view and uh, it kind of displays something, um, but it doesn't look good. Let's add the h tml safe dot h tml safe here. And here it's still doesn't, uh, look very good. Mm. Let's see why. Maybe we need to also mention format. HTML. Okay, yes, this helped. So here and here and, uh, we have the new version and the old version, but we want to show them side by side as GitHub does here. So we are going to, uh, add the diviv, uh, style, uh, display, uh, flex. And now they are kind of displayed side by side. Uh, obviously you can make the width of each, uh, column. Uh, same. Let's have a look at how it looks on the longer text. So here I have the normal column view and the differences and the split view looks, uh, much, uh, better. I have the old version and the new version side by side, and as this text alone that they can update even, uh, with. So yes, that's basically it. We built an app where we track the changes, uh, to the post title and the post, uh, body whenever something changes. And, uh, We can see the change history of the body and of the, uh, title and we can view the changes, uh, as a diff in the column view and in the split view. So that's about it. Thanks for being me and seeing in the next one.
8
Join the conversation
Sign in to leave comments and save lessons to your watchlist.
We collect your email address, name and username to create your account. We do not share your email address with anyone else.