- Read Tutorial
- Watch Guide Video
Now that we have our FactoryGirl
code in place for audit logs, let's add in some data validations.
Open the audit_log_spec.rb
file and add our first test case to check if the audit log can be created.
# spec/models/audit_log_spec.rb require 'rails_helper' RSpec.describe AuditLog, type: :model do before do @audit_log = FactoryGirl.create(:audit_log) end describe 'creation' do it 'can be properly created' do expect(@audit_log).to be_valid end end end
If you run rspec
, everything is green, and this is expected since our system already allows for creating audit logs. Usually I like to implement these type of base case scenarios to ensure that the tests are wired up properly. Next, let's implement some validations. Before we create the validations, let's list them out.
- Audit log should be associated with the user.
- Status is a required field
- Start date is required
- Start date should be equal to six days prior
The first three validations should be fairly straightforward.
The code for the first test is:
# spec/models/audit_log_spec.rb describe 'validations' do it 'it should be required to have a user association' do @audit_log.user_id = nil expect(@audit_log).to_not be_valid end end
As expected rspec
throws an error. Let's create the same tests for the status
and start_date
since the implementation for them is going to be the same.
# spec/models/audit_log_spec.rb it 'it should always have a status' do @audit_log.status = nil expect(@audit_log).to_not be_valid end it 'it should be required to have a start_date' do @audit_log.start_date = nil expect(@audit_log).to_not be_valid end
To fix these errors, open the audit_log.rb
model file and include this code:
# app/models/audit_log.rb validates_presence_of :user_id, :status, :start_date
Now, rspec
clears all these test failures for us.
Let's go to the last, and probably the most complex test. This test will confirm that the start date is six days prior. As a first step, let's create an audit log and store it in a local variable called new_audit_log
. Then, we are going to check if the start date is six days earlier. The code for that should be:
# spec/models/audit_log_spec.rb it 'it should have a start date equal to 6 days prior' do new_audit_log = AuditLog.create(user_id: User.last.id) expect(new_audit_log.start_date).to eq(Date.today - 6.days) end
Run rspec
, and we get the error we want. So, open audit_log.rb
and do a callback for a private method called set_defaults
. In this private method, our code should check if there is already a start date, and if there isn't one, it will add a date that is six days before today. Code for this functionality should look like this:
# app/models/audit_log.rb class AuditLog < ActiveRecord::Base belongs_to :user validates_presence_of :user_id, :status, :start_date after_initialize :set_defaults private def set_defaults self.start_date ||= Date.today - 6.days end end
If you run rspec
, everything works fine. Now, open the rails console in sandbox mode, and create an audit log with just the user id. It creates a record without any error even though status
and start_date
are required values. This is because the defaults are set by the code, and this is just what we want.