module HasUrl
extend ActiveSupport::Concern
included do
attr_accessor :bar
end
def bar
0
end
end
class Foo < ActiveRecord::Base
include HasUrl
end
The bar attribute is not stored in the database, but it is used in a form (using SimpleForm's f.input
). I'd like to override the getter for this method so I can set bar
based on other attributes and have the form properly pre-fill the value.
The problem is that using attr_accessor
in an included block like this will setup the getter on the Foo
class. Because the module is included above Foo
in the ancestor chain, the custom bar
method that returns 0 is never touched.
One way to solve this is
class Foo < ActiveRecord::Base
include HasUrl
def bar
super
end
end
But I want to avoid this extra step. I just want to include the module and have it just "work". Another option is to use different helpers in my form (f.input_field etc) but then I cannot take advantage of SimpleForm's wrappers.
Module#prepend will not solve my problems either, since HasUrl
also defines some other things (notably an ActiveRecord callback). If I prepend, these callbacks cause errors:
NoMethodError: undefined method `_run_...__find__...__callbacks`
Is there a way to get around this error so that prepend can work? Or another way to do this altogether?
Are you sure you want the attr_accessor
? Wouldn't an attr_writer
suffice?
require 'active_support/all'
module HasUrl
extend ActiveSupport::Concern
included do
attr_writer :bar
end
def bar
0
end
end
class Foo
include HasUrl
end
p Foo.new.bar
Anyhow, if you really want to use attr_accessor
, this should work:
require 'active_support/all'
module HasUrl
extend ActiveSupport::Concern
included do
attr_accessor :bar
define_method :bar do
0
end
end
end
class Foo
include HasUrl
end
p Foo.new.bar
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With