DEV Community

Discussion on: How to implement Policy Object pattern in Ruby on Rails?

Collapse
 
katafrakt profile image
Paweł Świątkowski

Policy objects are great. However, I don't 100% agree with examples in this post. Putting methods like active? in the model leads to fat models, but I'd argue it does not break the SRP (well... ActiveRecord itself breaks it, but it does not break it more than it's already broken ;) ). In your example, active? method relies solely on the state of the model instance, which IMO justifies putting it in the model.

In my mind policy objects usually coordinate the model with something else, often current_user. Having model know anything about current user is a huge smell, so policy object is much better at handling it. Something like this:

if Policies::Article.new(@article).can_update?(current_user)
  @article.save
end
Enter fullscreen mode Exit fullscreen mode

with

module Policies
  class Article
    def initialize(article)
      @article = article
    end

    def can_update?(user)
      user.role == :admin || @article.author_id == user.id
    end
  end
end
Enter fullscreen mode Exit fullscreen mode

I think this might be more convincing for people who want to put everything in the model.

Collapse
 
vladhilko profile image
Vlad Hilko

yeah, you're right, I probably wouldn't have created a Policy object for such example, I just wanted to show the idea and keep the code as simple and straightforward as possible :)

Collapse
 
katafrakt profile image
Paweł Świątkowski

Sure thing.

By the way, which do you think is better? ;)

Policies::Article.new(@article).can_update?(current_user)

# or

Policies::Article.new(current_user).can_update?(@article)
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
vladhilko profile image
Vlad Hilko

I think if we call it Policies::Article then we should accept article in the initializer, so I would go with the following:

Policies::Article.new(@article).can_be_updated_by?(current_user)

# or 

Policies::User.new(current_user).can_update?(@article)
Enter fullscreen mode Exit fullscreen mode