stevecross
stevecross

Reputation: 5684

Validate presence of has_one relation

I have two models which are associated:

class User < ActiveRecord::Base  
  belongs_to :role, dependent: :destroy, polymorphic: true

  validates :role, presence: true
end

class Admin < ActiveRecord::Base
  has_one :user, as: :role
  attr_accessible :user_attributes
  accepts_nested_attributes_for :user
end

How can I validate that a user exist if I save an admin?

Update

This are my tests:

factories.rb

FactoryGirl.define do
  sequence :email do |n|
    "foo#{n}@example.com"
  end

  factory :user do
    email
    password "secret12"
    password_confirmation "secret12"

    factory :admin_user do
      association :role, factory: :admin
    end
  end

  factory :admin do
    first_name "Max"
    last_name "Mustermann"
  end
end

user_spec.rb

require "spec_helper"

describe User do
  let(:user) { FactoryGirl.build(:user) }
  let(:admin) { FactoryGirl.build(:admin_user) }

  describe "sign up" do
    it "should not be valid without associated role" do
      user.should_not be_valid
    end

    it "should be valid with associated role" do
      admin.should be_valid
    end
  end
end

admin_spec.rb

require "spec_helper"

describe Admin do
  let(:admin_base) { FactoryGirl.build(:admin) }
  let(:admin_user) { FactoryGirl.build(:admin_user).admin }

  describe "sign up" do
    it "should not be possible without associated user" do
      admin_base.should_not be_valid
    end
  end

  it "should have a first name" do
    admin_user.first_name = ""
    admin_user.should_not be_valid
  end

  it "should have a last name" do
    admin_user.last_name = ""
    admin_user.should_not be_valid
  end

  it "should create a correct full name" do
    admin_user.full_name.should == "Max Mustermann"
  end
end

Only the first admin test fails at the moment, but if I validate the presence of user in the admin model almost all tests fail. Maybe my tests or factories are wrong?

Upvotes: 2

Views: 7179

Answers (3)

stevecross
stevecross

Reputation: 5684

My factories have been wrong. They should look like:

FactoryGirl.define do
  sequence :email do |n|
    "foo#{n}@example.com"
  end

  factory :user_base, class: User do
    email
    password "secret12"
    password_confirmation "secret12"

    factory :user_with_role do
      association :role, factory: :admin
    end
  end

  factory :admin_base, class: Admin do
    first_name "Max"
    last_name "Mustermann"

    factory :admin do
      association :user, factory: :user_base, strategy: :build
    end
  end
end

Now the test on validates :user, presence: true works as supposed.

Upvotes: 0

AnkitG
AnkitG

Reputation: 6568

You can use validates_associated .

class Admin < ActiveRecord::Base
  validates_associated :user
  validates_presence_of :user
end

NOTE: If you want to ensure that the association is both present and guaranteed to be valid, you also need to use validates_presence_of.

Upvotes: 10

renatojf
renatojf

Reputation: 744

I think you can still use the same validation on admin. It is supposed to work with relations as well.

try

validates :user, presence: true

Upvotes: 0

Related Questions