XYZ
XYZ

Reputation: 27427

FactoryGirl InvalidFactoryError NoMethodError

I have a card factory (defined below),

FactoryGirl.define do
  factory :card do
    front { Faker::Lorem.sentence }
    back { Faker::Lorem.sentence }
    tags { Faker::Lorem.words(3).join(';') }

    # associations
    user
    tag
  end
end

When I try to run the spec I get the following error,

An error occurred in a `before(:suite)` hook.
Failure/Error: FactoryGirl.lint

FactoryGirl::InvalidFactoryError:
  The following factories are invalid:

  * card - undefined method `each' for "eum;et;ad":String (NoMethodError)

I have no idea why this is happening, code below is my card model,

class Card < ApplicationRecord
  validates :front, presence: true

  belongs_to :user
  has_one :meta_sm2
  has_many :action_records
  has_and_belongs_to_many :tags

  delegate :username, :email, :name,
           to: :user, prefix: true
end

Upvotes: 1

Views: 605

Answers (3)

VAD
VAD

Reputation: 2401

Ok, you have an HABTM association between cards and tags. I don't really get how can you set tags with just an array or a string instead of associated objects but still I believe you want to set up correct HABTM association in your factories and one can do that like this:

FactoryGirl.define do
  factory :card do
    front { Faker::Lorem.sentence }
    back { Faker::Lorem.sentence }
    # tags { Faker::Lorem.words(3).join(';') }

    # associations
    user


    factory :card_with_tags do
      after(:create) do |book|
        create_list(:tag, 3, cards: [card])
      end
    end
  end
end

It's the "lighweight" way to set up HABTM in the factories. I've mentioned the "thorough" way in the one of my recent answers.

Upvotes: 1

XYZ
XYZ

Reputation: 27427

I have solved the issue by change the factory code to the code below,

FactoryGirl.define do
  factory :card do
    front { Faker::Lorem.sentence }
    back { Faker::Lorem.sentence }

    # associations
    user
    tag
    meta_sm2
    action_record
  end
end

I think the previous issue is related to the missing associations.

Upvotes: 0

Sravan
Sravan

Reputation: 18657

Since card has many-many association with tags

tags expects an array, instead you passed a string,

Try, tags { Faker::Lorem.words(3) } instead of tags { Faker::Lorem.words(3).join(';') }

FactoryGirl.define do
  factory :card do
    front { Faker::Lorem.sentence }
    back { Faker::Lorem.sentence }
    tags { Faker::Lorem.words(3) }

    # associations
    user
    tag
  end
end

Upvotes: 1

Related Questions