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: The check_expiry method is called before actions like show, edit, update, and destroy. 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! 😊💻

Follow Me