1

I'm adding a model to my project which shares a name with a class in the models directory, but it's in a module and has no relation (figuratively and literally) to the existing model: Offer and Partner::Offer.

+ app
|-+ models
  |-- offer.rb
  |-+ partner
    |- offer.rb

I generated the new model using rails new model Partner::Offer, and it generated the appropriate migration and FactoryBot factory, as well as the Partner module:

module Partner
  def self.table_name_prefix
    'partner_'
  end
end

Now, here's where I'm running into some weird behavior. I fired up the Rails console and tried to build a new Partner::Offer using the factory:

offer = FactoryBot.build(:partner_offer)

This returns an error: NoMethodError: undefined method 'external_id=' for #<Partner::Offer:0x0000000113622910>. external_id is an attribute on the top-level Offer model, but not on Partner::Offer.

It seems like the factory is instead trying to build the top-level Offer object instead. As a sanity check, I just typed in Partner::Offer.new and observed the results, and while the Class of the new object was correct, it had all the fields of the top-level Offer class.

I've never seen this behavior before. What could be causing the mix-up?

This is the Partner::Offers factory file:

FactoryBot.define do
  factory :partner_offer, class: 'Partner::Offer' do
    partner_id { SecureRandom.hex }
    expiration_date { 1.week.from_now }
    amount { 123.45 }
  end
end

Argus9
  • 1,863
  • 4
  • 26
  • 40

1 Answers1

1

I figured out what the issue was.

I have a clients folder in my project, which is a sibling of the models folder. And I have a client class there that shares a namespace with the Offer:

module Partner
  class Client
    ...
  end
end

It seems that this file is conflicting with the Partner module file. I fixed it by changing that module into a class under the Partner namespace:

class Partner::Base < ApplicationRecord
  self.abstract_class = true

  def self.table_name_prefix
    'partner_'
  end
end

class Partner::Offer < Partner::Base
  ...
end

Everything works fine now.

Argus9
  • 1,863
  • 4
  • 26
  • 40