Im just diving into the world of rails and ruby. Ive followed along a tutorial and i got the base of my app setup, but now i want to do some calculations wich don't really fit into the MVC scheme (or at least not like the rest of the stuff so far) and i don't know where to put and or handle them.
1. Ive got a form where a user can enter their weight, but for each new record I need some data from the record prior to this new one.
How would i go about that, where is the right moment to retrieve this data and should it be done inside the controller, model or elsewhere?
2. With every seventh entry (each week) i want to use those seven records and do some calculations (where should those calculations take place?) Also, with that seventh submission, i want to save those calculations in another model (1 post = 2 records in different models)
Would be awesome if you guys could help me and sorry if this is obvious stuff I am still really new to this.
2 thoughts on “Where to put my calculations?”
So to do the actual calculations, I would probably just create a module and stick that in your lib files. Then, when your controller needs to call an action, it should retrieve the data it needs from user and/or database and pass it to the appropriate method in the module.
You can put the calculations in to your controller, but this is generally frowned upon, as it’s quite hard to reuse.
Effectively you have some “task” objects – they’re not data themselves, but they perform operations on the task.
DHH (the inventor of Rails) would probably say you need a WeightInputsController that creates a WeightInput model. The WeightInput model can be a plain Ruby object (not an ActiveRecord model) and it can do the actual work – creating a WeightEntry model (which is stored in the database) and retrieving the previous WeightEntry to use its data; likewise it can decide if it’s the seventh day and act accordingly.
Personally, I would use the ActiveJob function in Rails – I would create a RecordsWeightEntryJob – and then call “RecordsWeightEntryJob.perform_now params: weight_entry_params”. This is quite unusual but is a pattern that is working out very well for me on some quite large projects (it also has the advantage that it’s easy to make some tasks work asynchronously but that’s not something you need to worry about at the moment)
Or as the other poster suggests, use an object in the lib folder.
In all cases, the idea is the same – you are doing some work that has logic over multiple models so you don’t want the actual work to be in an individual ActiveRecord model itself – so you move it into a separate object (DHH would say a model that isn’t backed by the database, many would say a “plain ruby object” in lib, I like to put my logic into ActiveJob)