TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Rails – The Missing Parts – Policies

63 pointsby nottombrownabout 11 years ago

8 comments

mjbellantoniabout 11 years ago
If I can overly generalize, and as a person who generally loves Ruby and Rails, I&#x27;ll suggest that there are two schools of Rails app development emerging.<p>The first is what I&#x27;ll term the &quot;Classic School&quot; or &quot;DHH School&quot; characterized by full-blown utilization of all Rails magic such as AR&#x2F;AC callbacks, pretty skinny but not obsessively skinny controllers, an eschewance of service objects and more.<p>The &quot;Emerging School&quot; relies less on some aspects of Rails magic, and introduces patterns like services&#x2F;interactors&#x2F;DCI and seems to be more focused on building a domain models which attempt to be less coupled to the framework.<p>I think the Grouper folks are in the second camp given their previous blog post about interactors which showed up here on HN. Also, I think the desire to encapsulate authorization into a reusable object seems slightly more in the spirit of the emerging school.<p>What I find odd is that they&#x27;d offer a solution for authorization which is so bound up in Rails magic. It seems to me authorization is really part of the domain model and as such you would expect to find that code in whatever gets called by the controller (which I would expect to be something like an interactor, but in this blog post is just plain old Rails code.)
评论 #7437757 未加载
评论 #7437364 未加载
评论 #7437460 未加载
dhhabout 11 years ago
Ensuring that the Ticket is valid is obviously a domain model concern. Policy objects can be a fine idea when they&#x27;re swappable and you need to allow for multiple different policies. This is not one of those cases.<p>Here&#x27;s a much simpler approach that keeps the validation logic in the domain model and uses features that Rails has had since the dawn of the framework: <a href="https://gist.github.com/dhh/9672827" rel="nofollow">https:&#x2F;&#x2F;gist.github.com&#x2F;dhh&#x2F;9672827</a>
评论 #7438449 未加载
评论 #7439765 未加载
评论 #7438932 未加载
dansoabout 11 years ago
Oh boy, is DHH going to jump into this too?<p>As an intermediate Rails developer...I don&#x27;t understand why this if&#x2F;else forest:<p><pre><code> if user.blacklisted? # They&#x27;ve been banned for bad-behaviour fail! “You can&#x27;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 </code></pre> -- can&#x27;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? &amp;&amp; user.not_booked(self.date)`) don&#x27;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?`<p>edit: OK, not ask for `ticket.confirmable?`, but rather, try to `save` the ticket and the Ticket constructor&#x2F;validators can pass on the errors to the controller.
评论 #7437572 未加载
评论 #7437318 未加载
评论 #7437351 未加载
swansonabout 11 years ago
How is a Policy different than an ActiveRecord::Validator? Could this TicketPolicy not just be a validator extracted to it&#x27;s own file (and tested on it&#x27;s own)?<p><a href="http://api.rubyonrails.org/classes/ActiveModel/Validator.html" rel="nofollow">http:&#x2F;&#x2F;api.rubyonrails.org&#x2F;classes&#x2F;ActiveModel&#x2F;Validator.htm...</a>
评论 #7443952 未加载
dpeckabout 11 years ago
related, Pundit provides some similar functionality in a very minimal package <a href="https://github.com/elabs/pundit" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;elabs&#x2F;pundit</a>
评论 #7437517 未加载
评论 #7437407 未加载
yxhuvudabout 11 years ago
While more interesting than the first part, it should be noted that the policy does not solve the same problem as the one they had originally, where different fail reasons led to different URLs.<p>If you only intend to redirect to one url in case of fail, then using normal validations (possibly on a service object implementing ActiveModel::Validations will suffice and produce as simple code as their solution.<p>Which isn&#x27;t saying that I dislike it, only that it is quite equivalent with a separate service model without controller integration.
评论 #7437449 未加载
Dorian-Marieabout 11 years ago
I would use CanCan ability.rb file for that: <a href="https://github.com/CanCanCommunity/cancancan" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;CanCanCommunity&#x2F;cancancan</a>
评论 #7438601 未加载
评论 #7437755 未加载
评论 #7437409 未加载
jvansabout 11 years ago
I think this is a responsibility that lies in the model. What if you decide to allocate tickets through a different model? You have to remember to include this policy everywhere. Another approach i think is reasonable is creating a class for this on the model level.<p><a href="https://gist.github.com/jvans1/9745395" rel="nofollow">https:&#x2F;&#x2F;gist.github.com&#x2F;jvans1&#x2F;9745395</a>