1

I have the following line of code which very simply decrements a Shareholders number of stocks (integer in the DB) when they sell them to someone else. This works well and as expected.

@selling_shareholder.update_attribute(:number_of_stocks, @selling_shareholder.number_of_stocks -= @transaction.number_of_stocks)

Very simply what I'd like to do is have the decrement function stop when the number_of_stocks hits 0 i.e. having a negative number should not be possible.

I guess I could use a simple unless @selling_shareholder.number_of_stocks > 0 at the end of the line, but I'm wondering if that will actually work without using a loop?

rock_n_rolla
  • 337
  • 3
  • 11
  • 2
    Riddle me this. How can one have a `transaction` with a `number_of_stocks` in excess of their `number_of_stocks`? This seems like a simple validation `validates :number_of_stocks, numericality: {greater_than_or_equal_to: 0}` or if transaction is linked to the share holder than validate the number of stocks in the transaction prior – engineersmnky Nov 14 '18 at 18:16
  • 1
    You are correct, I do not allow shareholders to sell more stocks than they own - and that is controlled in the view already, but what I was looking for here for some more assurance/safety on the back end - which now I've added via your model validation suggestion - thanks! :) – rock_n_rolla Nov 14 '18 at 19:59
  • 1
    On a side note, try to avoid using operators like `+=` or `-=` because they aren't [thread-safe](https://stackoverflow.com/a/15184752/1522214) – Eric Norcross Nov 14 '18 at 20:18
  • Thanks, makes sense! – rock_n_rolla Nov 15 '18 at 19:17

1 Answers1

4

I would suggest creating a method in your model called something like #decrement_stock that would handle that logic. You can set all kind of behaviors that should be expected, like raising exceptions. That approach follows the "tell don't ask" principle. It is also a simple unit of work performing a single task, making it easy to test with your favorite unit testing framework.

As engineersmnky suggested, simply adding validation on the model is also a good solution if you want the controller to handle errors.

Sophie Déziel
  • 428
  • 2
  • 11