GAURAV VARMA
ActiveRecord is
one of the most powerful features in Rails. With ActiveRecord we can easily
query and handle database objects without writing any SQL.
By using ActiveRecord Query Interface, we can perform various query operations
like Joins, Group, Find, Order. We can also chain relations with
where, and, or, not but for and or or the two chaining relations
must be structurally compatible.
For any two relations to be
Structurally Compatible
they must be scoping the same model, and they must differ only by the where
clause when no group clause has been defined. If a group clause is present
then the relations must differ by the having clause. Also, Neither relation
may use a limit, offset, or distinct method.
Previously for and or or query methods, we needed to make sure that the two
relations are structurally compatible otherwise ActiveRecord would raise an
error.
However,
Rails 7 has added ActiveRecord::Relation#structurally_compatible?
which provides a method to easily tell if two relations are structurally
compatible. We can use this method before we run and or or query methods on
any two relations.
Let's assume we have two models Blog and Post with the following relations
1# app/models/blog.rb
2class Blog < ApplicationRecord
3 has_many :posts
4end1# app/models/post.rb
2class Post < ApplicationRecord
3 belongs_to :blog
4endBefore
If we run or query between incompatible relations we would get an
ArgumentError.
1relation_1 = Blog.where(name: 'bigbinary blog')
2relation_2 = Blog.joins(:posts).where(posts: { user_id: current_user.id})
3
4begin
5 relation_1.or(relation_2)
6rescue ArgumentError
7 # Rescue ArgumentError
8endRails 7 onwards
We can check the structural compatibility of the two relations.
1relation_1 = Blog.where(name: 'bigbinary blog')
2relation_2 = Blog.where(user_id: current_user.id)
3
4if relation_1.structurally_compatible?(relation_2) # returns true
5 relation_1.or(relation_2)
6endCheck out this pull request for more details.
This article was originally published on this website.