Adding a Publication State to Articles
A new published_at column is introduced to distinguish between draft and published articles. This enables iterative editing before public visibility.
Database Migration Strategy
A migration file is created to modify the database schema without directly altering the table. The migration adds a nullable timestamp column and includes a corresponding down migration to remove it if needed.
Using Timestamps for Publishing
The published_at column stores a timestamp with timezone to indicate when an article is published. This supports chronological ordering and improves content freshness visibility for users and search engines.
Updating Queries
A new query retrieves only published articles by filtering where published_at is not null and ordering results in descending order. The insert query is also updated to include the new column.
Modifying the Data Model
The article model struct is extended to include the published_at field. Supporting helper methods and find functions are updated to accommodate this new attribute.
Implementing Published Article Retrieval
A dedicated function is added to fetch only published articles. The home controller is updated to use this function so that only published content appears on the homepage.
Handling Article Creation Logic
The create function now accepts a boolean flag to determine publication status. If published is true, the current timestamp is assigned; otherwise, the field remains null.
So far, we have been showing all the articles in our database. However, in a real life app, we will probably like to be able to work with an article for multiple iterations before we actually show it on the blog. To do that, we need a way of indicating whether an article is ready to be read or not. And to do that, I'm going to add a
a new column to the articles table, so we can indicate if this is published or if it's not published. So to do that, we're gonna say just create migrations, migrations, migrations, and we're gonna say all the articles table with published at column. No, I meant create my gradient. There we go, and we now have a new migration file. So I'm in the newly created migration file.
And when we talked earlier about evolving the database, this is one of those things where we have the history of our database in our migration files. So we are not going to be changing the table directly. We are going to be using this migration to have a very explicit state of our lifetime of the database. Right.
to actually add this column to the table, we're gonna say all the table if exists, exists, articles, and then we're gonna say add column, published, add, timestamp, width, time zone. This column is optional, and that is because we will first create an article, and if we decide to publish it, we will fill out this
this column, and if not, we will just leave it as a null value so that we can use that to indicate whether or not an article is in a draft state or in a published state. We're also going to be using a timestamp so that we can show on the block when something was released, as it's really useful for users to know how old is the content, but it's also very useful for search engines to know how, let's say, quote unquote fresh some
content is. Great. Then we also need our down migration. We're simply going to say alter, table, if exists. And we will then say articles, drop, column, published, add. And that is basically if announced. Now we can go back and forth in time. If you don't like this, we can always change it.
before we actually make modification to the real database. Let's jump out and say just up migrations. You can see we have now successfully applied this new migration and we have also gotten a new version for the database. All right, next I'm gonna jump into our queries file here for articles and we're gonna add a new statement called query
published articles and we expect to get many back. And we're gonna say select star from articles where published at is not null. And we're gonna order them in a descending order. So order by published at descending. And here we are simply just like
focusing on this newly added column. So we only get the ones that has a value here and we get them in the order of the latest ones showing up first. We also need to update the insert query because we now need to add the published add column. And we simply just add into the columns we insert right and then another argument.
So we have in total five arguments. We can now drop out and say just generate curious. Am I misspelling this? Yes, just generate curious. There we go. And again, sometimes the tool needs to get set up or downloaded dependencies. And are we actually going to have some curious? We are.
And now, if we just quickly go into our internal, we should have, you can see here, we have the published add field getting added to the insert article query. And do we have the published add? We have the published add. With all that out of the way, we also need to add the field to our model struct. So we can add here, published add, time dot time. And if it didn't go down to our helper method here, we can say we want
published ads to be added as well. There we go. So now all of our find function is actually using this or have this field available to them in from the database. And I'm going to keep them find articles function as it is and simply expose another function where we use or we find all the published articles. So if we go up here and grab this and we're going to rename it to published.
find published articles, we change the query to be, query, published articles. And then we can use this in the home controller to grab all of the published articles. The final thing we need to do in the models layer is we need to update the create article function. And in here we need to add a, actually we're gonna add a boolean called published set to a boole value.
So that whenever we create a new article, we can mark if it should be published because we might just create everything and want to go right and want to want to ship it. So in here, we now also add a published ad that is going to be a PG type time stamp. And we're going to pass our time value of time dot now.
And then since this can be a nullable field, we can pass this valid field again. And we simply say data published. So this is only valid if publish is equal to true. So now we actually have everything in place to create an article that is published and cure them and only show what we need in the home page. And finally, we just need to update the home controller to use this new findPubList
articles. You can just update really fast. There you go. And now only our published articles will show up in the home page.