Reputation: 3410
I have a Company
model with attr_accessor :administrator
, so when user creates company, he also need to fill some fields for administrator of this company. I'm trying to test, that he fill all fields correctly.
class Company < ActiveRecord::Base
attr_accessor :administrator
validates :name, presence: true
validates :administrator, presence: true, if: :administrator_is_valid?
private
def administrator_is_valid?
administrator[:name].present? and
administrator[:phone].present? and
administrator[:email].present? and
administrator[:password].present? and
administrator[:password_confirmation].present? and
administrator[:password] == administrator[:password_confirmation]
end
end
company_spec.rb
is:
require 'rails_helper'
describe Company do
it 'is valid with name and administrator' do
company = Company.new(name: 'Company',
administrator: {
name: nil,
email: nil,
phone: nil,
password: 'password',
password_confirmation: ''
})
expect(company).to be_valid
end
end
So, as you see, I have a lot of mistakes in validation test, but RSpec pass it.
Thanks!
Upvotes: 0
Views: 366
Reputation:
You could clean up your code like this:
validate :administrator_is_valid?
private
def administrator_is_valid?
if administrator_cols_present? && administrator_passwords_match?
true
else
errors.add(:administrator, 'is not valid')
end
end
def administrator_cols_present?
%w(name phone email password password_confirmation).all? do |col|
administrator[col.to_sym].present? # or use %i() instead of to_sym
end
end
def administrator_passwords_match?
administrator[:password] == administrator[:password_confirmation]
end
Another improvement might be to move your administrator
to a struct, then call valid?
on the object.
admin = Struct.new(cols) do
def valid?
cols_present? && passwords_match?
end
def cols_present?
cols.values.all? { |col| col.present? }
end
def passwords_match?
cols[:password] == cols[:password_confirmation]
end
end
Then:
validate :administrator_is_valid?
def admin_struct
@admin_struct ||= admin.new(administrator)
end
def administrator_is_valid?
errors.add(:administrator, 'is not valid') unless admin_struct.valid?
end
Upvotes: 1
Reputation: 6223
That's because you didn't construct your validation properly. See, if: administrator_is_valid?
will return false for your test, telling Rails to skip this validation rule.
I suggest you drop using the presence validator in favor of using administrator_is_valid?
method as a validation method, because after all, if the administrator is valid then it is present. The code should look like this
validate :administrator_is_valid?
private
def administrator_is_valid?
(administrator[:name].present? and
administrator[:phone].present? and
administrator[:email].present? and
administrator[:password].present? and
administrator[:password_confirmation].present? and
administrator[:password] == administrator[:password_confirmation]) or
errors.add(:administrator, 'is not valid')
end
Upvotes: 1