related, Pundit provides some similar functionality in a very minimal package https://github.com/elabs/pundit
Rails – The Missing Parts – Policies
11–20 of 65 posts
Re: Rails – The Missing Parts – Policies
#12I would use CanCan ability.rb file for that: https://github.com/CanCanCommunity/cancancan
Re: Rails – The Missing Parts – Policies
#13While 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. 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. Which isn…
However, the OP apparently realized in the refactoring that it made more sense to simply have two paths...or setup a convention so that `redirect` can infer the correct error page from the error itself. If the OP had insisted that the Policy keep the path logic, I'm sure DHH would jump all over that as being bad-design-looking-for-a-solution.
Re: Rails – The Missing Parts – Policies
#14If I can overly generalize, and as a person who generally loves Ruby and Rails, I'll suggest that there are two schools of Rails app development emerging. The first is what I'll term the "Classic School" or "DHH School" characterized by full-blown utilization of all Rails magic such as AR/AC callbacks, pretty skinny but not obsessively skinny controllers, an eschewance of service objects and more. The "Emerging Schoo…
But I don't think that moving towards more single-responsibility objects means you have to give up all that Rails offers - particularly the preference for concise, human-readable APIs and convention-over-configuration. Ie, we don't need tonnes of boiler-plate just because we want to use more objects.
We put this permission check in the controller and not the interactor because it seems like the controller should generally be responsible for authentication & permissioning. Once you get to the interactor, it should just be told "Perform this interaction". Not "check if you can perform it, and then perform it".
Re: Rails – The Missing Parts – Policies
#15related, Pundit provides some similar functionality in a very minimal package https://github.com/elabs/pundit
We have abilities, which is just a table full of strings like "modify users". The policy (from Pundit) looks these up to find whether an actor (user, typically) can do something to a model.
We have roles, which is just a user-definable collection of abilities, so you might define an 'admin' role that has every permission, and a 'reporter' role that has the ability to run reports and not much else.
We have permissions, which includes a role, a manager, and a manageable. The manager is the actor, or the thing asking to do something to another object; the managable is the object the actor is trying to act upon.
There is a "Managable" concern that gets included in any object that may be guarded by policies, and a "Manager" concern that gets added to any object that might be an actor. The Manager concern sets up the associations gives us methods like "#has_ability_on(ability, managable)", and "#has_ability)", which is useful for deciding whether to show gui widgets. These methods are how Pundit looks up the abilities one (manager) object has on another (managable) object.
This simple setup has allowed us to greatly simplify our application.
Re: Rails – The Missing Parts – Policies
#16While 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. 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. Which isn…
Yeah, I agree with you...I think the implication is that the original implementation was bad for various reasons, among them, redirecting to different URLs based on error. But if in fact, that kind of redirection needed to be done (which would seem to be a mild violation of best-OOP practices), then I'd agree, a Policy object that lived outside of the Model and the Controller would be needed. However, the OP apparent…
We didn't want the Policy object to know about the redirect paths, so we opted to cut down the number of responses available - we simply redirect_to :back by default, but this can be configured in the controller.
Re: Rails – The Missing Parts – Policies
#17Oh 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! “Yo…
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).
Re: Rails – The Missing Parts – Policies
#18related, Pundit provides some similar functionality in a very minimal package https://github.com/elabs/pundit
We've been using Pundit with great success in our organization. We use it along with a few other objects described below. We have abilities, which is just a table full of strings like "modify users". The policy (from Pundit) looks these up to find whether an actor (user, typically) can do something to a model. We have roles, which is just a user-definable collection of abilities, so you might define an 'admin' role t…
I'm just using Pundit in a "real" app for the first time where strict user types won't be enough and I need to have a role based approach. I'm doing something similar to what you have now, but a couple steps back in my design process, and the managable concern sounds promising.
Re: Rails – The Missing Parts – Policies
#19related, Pundit provides some similar functionality in a very minimal package https://github.com/elabs/pundit
We use pundit more often these days to cancan, I would recommend it.
Re: Rails – The Missing Parts – Policies
#20I would use CanCan ability.rb file for that: https://github.com/CanCanCommunity/cancancan