2012-03-27 20 views
2

對於來自非ActiveRecord環境的人來說,複雜的查詢具有挑戰性。我在編寫SQL時很瞭解自己的方式,但是我很難理解如何在AREL中完成某些查詢。我試着自己找出下面的例子,但我似乎無法找到正確的答案。將從SQL複雜的查詢導入到AREL

這裏有一些原因,爲什麼我會爲AREL選擇我目前find_by_sql三通的方式來代替:在我的模型

  • 更乾淨的代碼。
  • 簡單的代碼(當這個查詢結合使用分頁鏈接因的。)
  • 更多的DB-兼容性(例如,我已經習慣了在GROUP BY topics.id指定所有列的代替,我用我的SELECT 。第

這裏是我的模型的簡化版本:

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 

只要我能,我試圖通過AREL寫這樣的東西,而不是在SQL(對於原因前面提到過),但我無法理解我的頭腦非基本的例子如上所述。

Fyi我並不是真的希望將這些方法直接轉換爲AREL,對解決方案的任何方向或洞察力都是值得歡迎的。 另一種說法,如果你認爲這是完全可以接受的解決方案,用sql-finder寫這些查詢,請分享你的想法。

注:如果我需要提供更多的範例,請告訴我,我會:)

回答

1

對於任何不需要自定義連接或條款 - 即可以映射到AR的關係 - 你可能想使用squeel而不是arel。 AREL基本上是一個重量級的關係代數DSL,您可以使用它在ruby中從頭開始編寫SQL查詢。 Squeel更主動的記錄查詢方式,可以消除大多數情況下使用SQL字面語句的情況。