In this article, we learned about another Ruby On Rails Design Pattern – Query Object

Rails Query Object is a type of design pattern that lets us fetch query logic from Controllers and Models into reusable classes.
While this article is written with Ruby On Rails in mind, it easily applies to other frameworks, especially MVC based and applying ActiveRecord pattern.
Let’s have a look at the below example
We want to request a list of posts with the type “video” that has a view count greater than 1000 and that the current user can access.
Class PostController < ApplicationController
def index @posts = Post.accessible_by(current_ability)
.where(type: :video)
.where('view_count > ?',1000)
end
end
The problems in the above code:
1) This code isn’t reusable
2) It’s hard to test the logic.
3) Any changes to the post schema can break this logic/code.
To make the controller light wight, readable, and neat we can use scopes
Class Post < ApplicationRecord
scope :video_type, -> { where(type: :video) }
scope :popular, -> { where ('view_count > ?',1000) }
scope :popular_video_type, -> { popular.video_type }
end
So, the controller will look like that:
Class PostController < ApplicationController
def index
@posts = Post.accessible_by(current_ability)
.popular_video_type
end
end
But still, it is not an appropriate solution; here we need to create scopes for every query condition we want to add, we are also increasing the code in the Model with various combinations of scope for diverse use cases.
To solve this kind of problem, we use the Rails Query Object:
video_query.rb
Class VideoQuery
def call(ability)
ability
.where(type: :video)
.where('view_count > ?', 1000)
end
end
post_controller.rb
Class PostController < ApplicationController
def index
ability = Post.accessible_by(current_ability)
@articles = VideoQuery.new.call(ability)
end
end
Now, it’s reusable! We can use this class to query any other models that have a similar scheme.
Conclusion
A query object is a simple, easily testable pattern that helps in abstracting queries, relations and scope chains with complex implementation.
In the next blog, We will learn about the Decorators Design Pattern.
“The decorator is a design pattern that allows the behavior to be added to an object, dynamically, without disturbing the behavior of other objects of the same class“
You can read about Ruby On Rails Design Pattern at https://runwithcode.blogspot.com/2020/04/design-patterns-in-ruby-on-rails.html
Thanks For Reading …