Let's say that we have a method inside a model that
Should the "save" calls happen inside the method itself like the following code
def result
save! if new_record?
# do some funky stuff here that may also change the model state
# ...
# And calculate the return value
search_result = "foo" # Let's say "foo" is the value we calculated
save! if changed?
search_result # return
end
Or should the external observer (the controller) be responsible for calling save as needed?
If your method really, really needs to do all that, so be it.
However, I would make it clear from looking at the method why you're doing that (comments might be good here), and would definitely make this a bang_method!
so that it is clear to whoever invokes it that this method is liable to mess with the object as much as it likes.
Also, the method name result
(which, I know, probably isn't your real method name) somewhat implies that you're just fetching data, and little more. Maybe load_result!
would be more appropriate here, to make it clearer that you're not just accessing an attribute, but are, in fact, performing heavy operations to get it.
There are definitely times when it is necessary for a model to persist itself. But it's worth considering whether save is the best method for your application.
In a current example, we have a model that processes a file asynchronously in a long-running method (we are spinning the process off using sidekiq.) Inside the method, a persistent attribute is updated regularly so the status information is available to other requests.
We're using update_column rather than save, because
Inside the model, methods like
etc, may often be a more appropriate way to persist changes than a plain save.
When does a program save data on a file?
a) Only when user requires it (directly or indirectly)? -- this is controller case
b) Only when the program achieves part of its correctness and data integrity? -- this is model case
c) Both.
I would vote for (c). I hope this discrimination straightens things a bit.
Additionally, from a object-oriented design point of view, method save() belongs to the public contract of its class; it can be invoked by anyone. Given this, a class is responsible for its public contract and, if needed, an object can invoke its own methods at will.
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