ChatGPT解决这个技术问题 Extra ChatGPT

FactoryBot 可以在您的模型创建后生成工厂吗?

When including the factory_bot_rails gem in your dev and test blocks in Gemfile, rails will generate factories automatically when your models are generated.

Is there a way to generate factories after your models have been generated?

Note: FactoryBot was previously named FactoryGirl

What exactly do you mean with "generating"? You have to define and call them explicitly.
@iltempo - I mean when you use the "factory_girl_rails" gem, when you generate your models via command as "rails g model User first_name:string"... etc. factories for this model are auto-generated just as a fixture is for testing. I was wondering if there was a way to use a generator hook after the model has been created.

n
notapatch

First thing, look at the source project to find out how it was implemented:

https://github.com/thoughtbot/factory_bot_rails/blob/master/lib/generators/factory_bot/model/model_generator.rb

After that, try to guess how it works:

rails g factory_bot:model Car name speed:integer

The result is:

create  test/factories/cars.rb

And the content:

# Read about factories at https://github.com/thoughtbot/factory_girl

FactoryBot.define do
   factory :car do
     name "MyString"
     speed 1
   end
end

Remember, when you use rails g, you can always undo it, with rails d

rails d factory_bot:model Car name speed:integer

Note: FactoryBot was previously named FactoryGirl


This should be the correct answer, because it answers the specific question about how to generate factories for models that have already been created. The common scenario is switching an existing rails app with default fixtures to using FactoryGirl
you don't even have to guess how it works, rails g factory_girl:model --help will tell you how.
Any way to create it under spec directory?
@juliangonzalez you can specify with --dir option. rails g factory_girl:model User --dir spec/factories
N
Nikita Fedyashev

The --fixture-replacement option will let you tell rails what to generate for building test data. You can set this as a default in your config/application.rb file, like so:

config.generators do |g|
  g.fixture_replacement :factory_bot, suffix_factory: 'factory'
end

Source: https://github.com/thoughtbot/factory_bot_rails/blob/master/features/fixture_replacement_config.feature#L21


That does the trick! It's amazing what you'll find when you just read through the documentation. :)
How does this answer the question ? How does it generate factories after the models were created ?
See answer from user2040729 below.
Who is user2040729? how this answer the question? how to use --fixture-replacement?
There's a great misunderstanding here. @GuiDoody was asking for the generator command called after a rails g model, not for a magic factory-creation using the model description in the schema for example. This option was discussed here: github.com/thoughtbot/factory_girl_rails/issues/63. @edouardo-santana and @cjhveal answers are both acceptable.
M
Mark Burns

I have a gem for exactly this https://github.com/markburns/to_factory


Thanks for the gem quite nice
D
Davinj

This works for me using rails g factory_bot:model User either running the command or just puts'ing the command out. You do still have to fill in the value.

@run_command        = true
@force              = true
@columns_to_ignore  = %w[id created_at update_at]
@tables_to_ignore = %w[schema_migrations ar_internal_metadata]
tables = ActiveRecord::Base.connection.tables.reject{|t| (@tables_to_ignore || []).include?(t)}

tables.each do |table|
  klass = table.singularize.camelcase.constantize
    command = "rails g factory_bot:model #{klass.to_s} #{klass.columns.reject do |c|
      (@columns_to_ignore || []).include?(c.name)
    end.map do |d|
      "#{d.name}:#{d.sql_type == 'jsonb' ? 'json' : d.type}"
  end.join(' ')}"
  command << ' --force' if @force
  puts command
  puts %x{#{command}} if @run_command
  puts (1..200).to_a.map{}.join('-')
end

This Answer must be the right answer which generates factories from DB. Awesome!! Kudos
f
frenesim

This is not an answer, but since I cannot comment yet: I think you can use this to solve part of your problem. You can use a gem called schema_to_scaffold to generate a factory_girl:model command string. It outputs:

rails generate factory_girl:model users fname:string lname:string bdate:date email:string encrypted_password:string

from your schema.rb or your renamed schema.rb.

Check here or here


K
Kaka Ruto

Configure Factory Bot as the fixture replacement so you do not have to create factories manually.

In config/application.rb:

config.generators do |g|
  g.test_framework :rspec, fixture: true
  g.fixture_replacement :factory_bot, dir: 'spec/factories'
end

For more: https://github.com/thoughtbot/factory_bot_rails/blob/master/features/fixture_replacement_config.feature


y
yen-jung Chen

Not exactly related.

I also built a gem to build factory from existing data.

Hopefully, it can help you speed up the process a bit......

puts FactoryBotFactory.build(User.new, file_path: 'spec/factories/user.rb')
puts FactoryBotFactory.build(User.last, file_path: 'spec/factories/user.rb')

# example output from User.new
FactoryBot.define do
  factory :user, class: User do
    id { nil }
    name { nil }
    created_at { nil }
    updated_at { nil }
    display_name { nil }
    image_url { nil }
    is_active { true }
  end
end

You can also configure customize converter if you need to built fake data.


G
Gary S. Weaver

Some good answers here, but another option is to use stepford. For some projects that use schemas that have foreign key constraints, the deep_* methods, etc. might help, and it is a simple way to generate factories via command-line.