Call private class method from private instance method
First let me try to explain why the code does not work
class MyModel < ActiveRecord::Base
def self.create_instance
model = MyModel.new
# in here, you are not inside of the instance scope, you are outside of the object
# so calling model.somemething can only access public method of the object.
model.init_some_dependencies
...
end
...
You could bypass private calling of the method with model.send :init_some_dependencies
. But I think in this case there is probably better solution.
I would guess that init_some_dependencies
probably contain more business / domain logic rather than persistence. That's why I would suggest to pull out this logic into a "Domain Object" (or some call it Service Object). Which is just a plain ruby object that contain domain logic.
This way you could separate persistence logic to ActiveRecord and the domain logic to that class. Hence you will not bloat the ActiveRecord Model. And you get the bonus of testing the domain logic without the need of ActiveRecord. This will make your test faster.
You could create a file say `lib/MyModelDomain.rb'
class MyModelDomain
attr_accessor :my_model
def initialize(my_model)
@my_model = my_model
end
def init_some_dependencies
my_model.property = 'some value example'
end
end
Now you could use this object say something like this
class MyModel < ActiveRecord::Base
def self.create_instance
model = MyModel.new
domain = MyModelDomain.new(model)
domain.init_some_dependencies
domain.my_model
end
def initialize_instance
# do some other work
other_init
domain = MyModelDomain.new(self)
domain.init_some_dependencies
end
end
You might also want to move the initialize_instance
if you think it's necessary
Some resource that go deep into this pattern:
- http://railscasts.com/episodes/398-service-objects
- https://www.destroyallsoftware.com/screencasts/catalog/extracting-domain-objects
You can use
model = MyModel.new
model.send :init_some_dependencies
to bypass method visibility checks.