diff --git a/lib/factory_bot/strategy/stub.rb b/lib/factory_bot/strategy/stub.rb index d18b28f..bc5f309 100644 --- a/lib/factory_bot/strategy/stub.rb +++ b/lib/factory_bot/strategy/stub.rb @@ -44,15 +44,17 @@ module FactoryBot end def stub_database_interaction_on_result(result_instance) - result_instance.id ||= next_id + if has_settable_id?(result_instance) + result_instance.id ||= next_id + end result_instance.instance_eval do def persisted? - !new_record? + true end def new_record? - id.nil? + false end def destroyed? @@ -68,6 +70,11 @@ module FactoryBot end end + def has_settable_id?(result_instance) + !result_instance.class.respond_to?(:primary_key) || + result_instance.class.primary_key + end + def clear_changes_information(result_instance) if result_instance.respond_to?(:clear_changes_information) result_instance.clear_changes_information diff --git a/spec/acceptance/stub_spec.rb b/spec/acceptance/stub_spec.rb index dac6bfd..0065860 100644 --- a/spec/acceptance/stub_spec.rb +++ b/spec/acceptance/stub_spec.rb @@ -58,3 +58,44 @@ describe "a stubbed instance overriding strategy" do expect(subject.user).not_to be_new_record end end + +describe "a stubbed instance with no primary key" do + it "builds a stubbed instance" do + using_model_without_pk do + FactoryBot.define do + factory :model_without_pk + end + + model = FactoryBot.build_stubbed(:model_without_pk) + expect(model).to be_truthy + end + end + + it "behaves like a persisted record" do + using_model_without_pk do + FactoryBot.define do + factory :model_without_pk + end + + model = FactoryBot.build_stubbed(:model_without_pk) + expect(model).to be_persisted + expect(model).not_to be_new_record + end + end + + def using_model_without_pk + define_class("ModelWithoutPk", ActiveRecord::Base) + + connection = ActiveRecord::Base.connection + begin + clear_generated_table("model_without_pks") + connection.create_table("model_without_pks", id: false) do |t| + t.column :updated_at, :datetime + end + + yield + ensure + clear_generated_table("model_without_pks") + end + end +end diff --git a/spec/support/macros/define_constant.rb b/spec/support/macros/define_constant.rb index 07155e0..90f84c8 100644 --- a/spec/support/macros/define_constant.rb +++ b/spec/support/macros/define_constant.rb @@ -33,13 +33,17 @@ module DefineConstantMacros def clear_generated_tables created_tables.each do |table_name| - ActiveRecord::Base. - connection. - execute("DROP TABLE IF EXISTS #{table_name}") + clear_generated_table(table_name) end created_tables.clear end + def clear_generated_table(table_name) + ActiveRecord::Base. + connection. + execute("DROP TABLE IF EXISTS #{table_name}") + end + private def created_tables