|
|
|
|
|
by danso
4469 days ago
|
|
Oh boy, is DHH going to jump into this too? As an intermediate Rails developer...I don't understand why this if/else forest: if user.blacklisted? # They've been banned for bad-behaviour
fail! “You can't book a Grouper at this time”
elsif grouper.full?
fail! “This grouper is full, please pick another date”
elsif grouper.past?
fail! “This grouper has already occured!”
elsif user.has_existing_grouper?(grouper)
fail! “You’re already going on a Grouper that day”
elsif ticket.confirmed?
fail! “You’ve already confirmed this grouper”
end
-- can't simply be part of the Ticket object? The Ticket clearly has a relation to User and Grouper and talking to those objects (i.e. `if user.not_blacklisted? && user.not_booked(self.date)`) don't violate Demeter...how is making a policy object cleaner than just using a Concern that is included into Ticket? The controller then just needs to ask for `ticket.confirmable?`edit: OK, not ask for `ticket.confirmable?`, but rather, try to `save` the ticket and the Ticket constructor/validators can pass on the errors to the controller. |
|
This tends to cause a lot of problems - it's hard to exercise a single model in tests without having a very large number of associated objects present. This also tends to require them to be in the database. This makes your tests very slow, and your application very tightly coupled and hard to refactor.
If you rethink your Rails application and make models responsible for only data validation & persistence, you tend to avoid these kinds of problems. You then need somewhere else for the "core" of your application logic to reside. We suggest these new concepts are Interactors, Policies (and Decorators - more to come in a new blog post).