Reputation:
For someone who is coming from a non ActiveRecord environment, complex queries are challenging. I know my way quite well in writing SQL's, however I'm having difficulties figuring out how to achieve certain queries in solely AREL. I tried figuring out the examples below by myself, but I can't seem to find the correct answers.
Here are some reasons as to why I'd opt for the AREL way instead of my current find_by_sql
-way:
GROUP BY topics.id
in stead of specifying all columns I'm using in my SELECT
clause.Here are the simplified version of my models:
class Support::Forum < ActiveRecord::Base
has_many :topics
def self.top
Support::Forum.find_by_sql "SELECT forum.id, forum.title, forum.description, SUM(topic.replies_count) AS count FROM support_forums forum, support_topics topic WHERE forum.id = topic.forum_id AND forum.group = 'theme support' GROUP BY forum.id, forum.title, forum.description ORDER BY count DESC, id DESC LIMIT 4;"
end
def ordered_topics
Support::Topic.find_by_sql(["SELECT topics.* FROM support_forums forums, support_topics topics, support_replies replies WHERE forums.id = ? AND forums.id = topics.forum_id AND topics.id = replies.topic_id GROUP BY topics.id ORDER BY topics.pinned DESC, MAX(replies.id) DESC;", self.id])
end
def last_topic
Support::Topic.find_by_sql(["SELECT topics.id, topics.title FROM support_forums forums, support_topics topics, support_replies replies WHERE forums.id = ? AND forums.id = topics.forum_id AND topics.id = replies.topic_id GROUP BY topics.id, topics.title, topics.pinned ORDER BY MAX(replies.id) DESC LIMIT 1;", self.id]).first
end
end
class Support::Topic < ActiveRecord::Base
belongs_to :forum, counter_cache: true
has_many :replies
end
class Support::Reply < ActiveRecord::Base
belongs_to :topic, counter_cache: true
end
Whenever I can, I try to write stuff like this via AREL and not in SQL (for the reasons mentioned before), but I just can't get my head around the non-basic examples such as the ones above.
Fyi I'm not really looking for straight conversions of these methods to AREL, any directions or insight towards a solution are welcome. Another remark if you however think this is perfectly acceptable solution to write these queries with an sql-finder, please share your thoughts.
Note: If I need to provide additional examples, please say so and I will :)
Upvotes: 2
Views: 883
Reputation: 43042
For anything that doesn't require custom joins or on clauses - i.e. can be mapped to AR relations - you might want to use squeel instead of arel. AREL is basically a heavyweight relational algebra DSL which you can use to write SQL queries from scratch in ruby. Squeel is more of a fancier DSL for active record queries that eliminates most cases where you would use SQL literal statements.
Upvotes: 1