Rails 4: Set enum field through FactoryGirl attributes
Asked Answered
S

3

7

I have a Model that has an enum as attribute.

class ApplicationLetter < ActiveRecord::Base
  belongs_to :user
  belongs_to :event

  validates :user, :event, presence: true

  enum status: {accepted: 1, rejected: 0, pending: 2}

end

As well as a factory that generates this model and sets a value for the enum

FactoryGirl.define do
  factory :application_letter do
    motivation "motivation"
    user
    event
    status :accepted
  end
end

In a controller test I want to get valid attributes through the factory

let(:valid_attributes) { FactoryGirl.build(:application_letter).attributes }

and create a application with these attributes.

application = ApplicationLetter.create! valid_attributes

But I get the following error:

ArgumentError: '1' is not a valid status

Why is status interpreted as string? If I change the status in the factory I get the same error, but with the right corresponding number.

Sumatra answered 27/11, 2016 at 14:51 Comment(2)
Possible duplicate of Factory Girl with enum and associationSlightly
Looks like a duplicate of #27606797, but there's no good answer there either. Might want to report this on GitHub if it's still a problem.Slightly
D
1
let(:valid_attributes) { FactoryGirl.build(:application_letter).attributes.merge(status: 'accepted') }
Daggna answered 27/11, 2016 at 15:0 Comment(5)
Thanks for your fast response. Unfortunately it does not help. The error remains exactly the same :/Sumatra
Also, what type of data is stored in the status column in you db? It is an integer field, correct?Daggna
Yes it is an integer. Now it works with your updated answer and if I remove the entry in the factory. It looks a little bit hacky, but at least it works. Thank you very much :)Sumatra
if it solved your issue could you accept the answer?Daggna
The solutions looks a little bit "hacky" for me. I am relatively new to Rails (and Ruby in general) but I think it would be nice to set the status in the factory directly like the other attributes. I already have upvoted your answer and it was indeed very helpful, but maybe their is a better solution which looks cleaner to me. If such a solution does not exists I will of course accept your answer :)Sumatra
S
8

you can do it more dynamically:

FactoryGirl.define do
  factory :application_letter do
    motivation "motivation"
    user
    event
    status { ApplicationLetter.statuses.values.sample }
  end
end

in this each time you will get different status

OR if wanna use static value you have to use integer, because enums by default use integer values

Syntax answered 27/11, 2016 at 18:16 Comment(0)
C
3

All you need in your factory is status 'accepted'.

Charmer answered 6/11, 2018 at 21:28 Comment(0)
D
1
let(:valid_attributes) { FactoryGirl.build(:application_letter).attributes.merge(status: 'accepted') }
Daggna answered 27/11, 2016 at 15:0 Comment(5)
Thanks for your fast response. Unfortunately it does not help. The error remains exactly the same :/Sumatra
Also, what type of data is stored in the status column in you db? It is an integer field, correct?Daggna
Yes it is an integer. Now it works with your updated answer and if I remove the entry in the factory. It looks a little bit hacky, but at least it works. Thank you very much :)Sumatra
if it solved your issue could you accept the answer?Daggna
The solutions looks a little bit "hacky" for me. I am relatively new to Rails (and Ruby in general) but I think it would be nice to set the status in the factory directly like the other attributes. I already have upvoted your answer and it was indeed very helpful, but maybe their is a better solution which looks cleaner to me. If such a solution does not exists I will of course accept your answer :)Sumatra

© 2022 - 2024 — McMap. All rights reserved.