I'm implementing a plugin to Foreman v3.3.0 that should add some additional parameters to the Subnet model.
# app/models/subnet_extensions.rb
module SubnetExtensions
extend ActiveSupport::Concern
included do
has_one :subnet_bgp_config
end
end
# lib/engine.rb
class Engine < Rails::Engine
config.to_prepare
Subnet.include SubnetExtensions
end
end
Subnets in Foreman are implemented with single table inheritance (STI) and types Subnet::Ipv6
and Subnet::Ipv4
. My issue for the plugin comes up whenever the page for any subnet is rendered:
Association named ‘subnet_bgp_config’ was not found on Subnet::Ipv4; perhaps you misspelled it?
In the Rails console, I can verify that the association simply is not present for the subclasses:
# foreman-rake console (Rails 6.1.7)
irb(main):001:0> Subnet.reflect_on_all_associations.map(&:name).include? :subnet_bgp_config
=> true
irb(main):002:0> Subnet::Ipv4.reflect_on_all_associations.map(&:name).include? :subnet_bgp_config
=> false
I've validated, that this approach works just fine, when the has_one
association is written into the Foreman source code. So somehow the method of adding the plugin to Foreman breaks the inheritance.
Even including SubnetExtensions
in the console does not work (nor does it raise an error):
irb(main):001:0> Subnet::Ipv4.include ForemanSubnetsWithBGPConfig::SubnetExtensions
=> Subnet::Ipv4(id: integer, network: string, mask: string, priority: integer, name: text, vlanid: integer, created_at: datetime, updated_at: datetime, dhcp_id: integer, tftp_id: integer, gateway: string, dns_primary: string, dns_secondary: string, from: string, to: string, dns_id: integer, boot_mode: string, ipam: string, discovery_id: integer, type: string, description: text, mtu: integer, template_id: integer, httpboot_id: integer, netdb_id: integer, nic_delay: integer, externalipam_id: integer, externalipam_group: text, bmc_id: integer)
irb(main):002:0> Subnet::Ipv4.reflect_on_all_associations.map(&:name).include? :subnet_bgp_config
=> false
Can somebody give hints on what went wrong or pointers what to inspect/try next?
Asking for help on the Foreman developer forum more or less confirms that the issue lies with the load order specific to Foreman. At least the current development branch, which has switched to Rails-7 and Zeitwerk autoloader does not show the same symptoms.