How to Set and Validate Expiry Dates in a Ruby on Rails Application
August 31, 2024
In this tutorial, we'll walk through the process of setting an expiry date for articles in a Ruby on Rails application. We'll also ensure that users can't set an expiry date in the past, while allowing updates without forcing changes to the existing expiry date. This guide includes full code examples, making it easy to implement this feature in your Rails app.
Why Set an Expiry Date?
Setting an expiry date is useful when you want content to be automatically marked as outdated after a certain time. For example, news articles, event announcements, or limited-time offers can expire after a specific date, ensuring that only relevant content is shown to users.
Step 1: Adding an Expiry Date to Articles
First, ensure your articles
table has an expiry_date
column. You can add this column using a migration:
rails generate migration AddExpiryDateToArticles expiry_date:date
rails db:migrate
This adds the expiry_date
column to your articles
table, where you can store the expiry date for each article.
Step 2: Validating the Expiry Date
To prevent users from setting an expiry date in the past, add a validation to your Article
model. This validation will only trigger when the expiry date is being changed:
class Article < ApplicationRecord
validate :expiry_date_cannot_be_in_the_past, if: :expiry_date_changed?
private
def expiry_date_cannot_be_in_the_past
if expiry_date.present? && expiry_date < Date.today
errors.add(:expiry_date, "can't be in the past")
end
end
end
Explanation
expiry_date_changed?
: This method checks if the expiry date has been altered in the form submission. If the expiry date is being changed, the validation runs to ensure it's not in the past.- Custom Validation: The
expiry_date_cannot_be_in_the_past
method adds an error message if the date is before today.
Step 3: Handling Expired Articles
Next, you want to ensure that expired articles can't be accessed. You can achieve this by adding a before_action
in your ArticlesController
to check if the article has expired:
class ArticlesController < ApplicationController
before_action :check_expiry, only: [:show, :edit, :update, :destroy]
private
def check_expiry
@article = Article.find(params[:id])
if @article.expiry_date.present? && @article.expiry_date < Time.current
redirect_to root_path, notice: "This article has expired."
end
end
end
Explanation
before_action
: Thecheck_expiry
method is called before actions likeshow
,edit
,update
, anddestroy
. If the article's expiry date is in the past, the user is redirected to the root page with a notice.
Step 4: Display Validation Errors in the Form
To give users feedback when they try to set an expiry date in the past, ensure your form displays validation errors:
<%= form_with(model: @article, local: true) do |form| %>
<% if @article.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@article.errors.count, "error") %> prohibited this article from being saved:</h2>
<ul>
<% @article.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :expiry_date %>
<%= form.date_select :expiry_date %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
Explanation
- Error Display: If validation fails (e.g., trying to set a past expiry date), the errors will be shown above the form.
Conclusion
By following these steps, you've implemented a robust expiry date feature in your Ruby on Rails application. Users are prevented from setting dates in the past, while expired articles are automatically redirected, maintaining the integrity of your content. This feature is particularly useful for managing time-sensitive content, ensuring your users always see relevant information.
Implement these changes in your Rails application to control content visibility effectively, keeping your site fresh and user-friendly.
Happy coding! 😊💻