Attribute not being overridden when method is defined inside an ActiveSupport::Concern
aar0nr opened this issue · 6 comments
Given the following code...
module Serviceable
extend ActiveSupport::Concern
included do
attribute :services, :string
end
def services
raise "foo"
end
end
class Project < ActiveType::Object
include Serviceable
end
I would expect calling the services
method to raise an exception, but it returns nil
.
Project.new.services
# => nil
Rewritten to use ActiveModel
, it works as expected.
class Project
include ActiveModel::Model
include ActiveModel::Attributes
include Serviceable
end
Project.new.services
# => RuntimeError (foo)
However, it works with ActiveType when not using a module:
class Project < ActiveType::Object
attribute :services, :string
def services
raise "foo"
end
end
Project.new.services
# => RuntimeError (foo)
Any ideas?
Versions:
rails (6.0.2.2)
active_type (1.3.1)
When using ActiveSupport::Concern
, both the overridden services
method as well as the method defined by attribute
are defined in modules that just happen to be included in the "wrong" order.
I think we build the anonymous module for the attribute methods lazily. Maybe a fix could be to build and include it as soon as possible.
As a workaround you might consider using a Modularity trait instead of ActiveSupport::Concern
:
module Serviceable
as_trait do
attribute :services, :string
def services
raise "foo"
end
end
end
class Project < ActiveType::Object
include Serviceable
end
Project.new.services # raises "foo"
Thanks for the reply guys. Here is a more simple example without using a concern.
module Serviceable
def services
raise "foo"
end
end
class Project < ActiveType::Object
include Serviceable
attribute :services, :string
end
Project.new.services
# => nil
Now we try including the module after the attribute, and it works as expected...
class Project < ActiveType::Object
attribute :services, :string
include Serviceable
end
Project.new.services
# => RuntimeError (foo)
When using
ActiveSupport::Concern
, both the overriddenservices
method as well as the method defined byattribute
are defined in modules that just happen to be included in the "wrong" order.I think we build the anonymous module for the attribute methods lazily. Maybe a fix could be to build and include it as soon as possible.
@kratob Hello again. Yes, I think it would be good to mirror the behavior of Rails. I just spent some time slamming my head against my keyboard until I remembered why this wasn't working as expected. Doh! 😄
It turns out to be quite difficult to fix it. It is certainly doable (since ActiveRecord does it), but we did not find a simple consistent way to do it.
We would accept a PR that fixes this in a clean way, but will not try to fix it ourselves.