I have an Account, User and Group model. All User and Group records belong to an Account, so it is possible for both users and groups to be related to various accounts.
Basically, I have some really hacky, pieced together SQL queries that lookup all Account records related to a given User or Group record through various
associations.
Even though it's fast and only requires a single query for everything to work, I really hate the way it's written.
I was wondering if there is any way I could do this more programatically with something like arel, or if there was a better approach. I also have some security concerns about the code.
class Account < ActiveRecord::Base
belongs_to :accountable, touch: true, polymorphic: true
CLAUSE_FOR_RELATED = '"accounts"."accountable_type" = \'%s\' AND "accounts"."accountable_id" IN (%s)'.freeze
def self.related_to_user(user)
groups = user.groups.select('"groups".id')
friends = user.following_friendships.select('"friendships".following_id')
queries = []
queries.push ['Group', groups.to_sql]
queries.push ['User', friends.to_sql]
queries.push ['User', user.id]
self.related_to(queries)
end
def self.related_to_group(group)
queries = [
['User', group.members.select('"users".id').to_sql]
]
self.related_to(queries)
end
def self.related_to(queries)
clauses = queries.map do |clause|
sprintf(CLAUSE_FOR_RELATED, clause[0], clause[1])
end
self.where(clauses.join(" OR "))
end
end