2012-03-27 11 views
2

ActiveRecord以外の環境から来ている人にとって、複雑なクエリは困難です。私はSQLを書く上で私の道をはっきりと知っていますが、ARELだけで特定のクエリをどのように達成するのかがわかりません。下の例を自分で試してみましたが、正解を見つけることができません。私のモデルでSQLからARELへの複雑なクエリのレンダリング

  • クリーナーコード:ここで

    は私が道の代わりに私の現在のfind_by_sql -wayのARELを選ぶだろう理由としていくつかの理由です。 (このクエリがあるため、連鎖の改ページと組み合わせて使用​​されている。)

  • よりシンプルなコード
  • よりマルチDB-互換性(私は私のSELECTで使用しているすべての列を指定する代わりにGROUP BY topics.idに慣れ例えば。句
  • ここ

は私のモデルの簡易版です:私は、私が(前に述べた理由のために)SQLでARELなく経由して、このようなものを書いてみることができますたび

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 

が、私はちょうど私の頭の周りを得ることができない上記のような非基本的な例。

Fyi私はこれらのメソッドをARELに直接変換することは実際には考えていませんが、解決策の方向性や洞察は大歓迎です。 しかし、これがSQLファインダでこれらのクエリを書くのに完全に受け入れられるソリューションだと思うなら、あなたの考えを分けてください。

注:私は、追加の例を提供する必要がある場合は、そう言うと、私はカスタム・ジョインまたは句に必要としないものについて

答えて

1

:)をしますしてください - つまりは、AR関係にマッピングすることができます - あなたが望むかもしれませんarelの代わりにsqueelを使用してください。 ARELは、基本的には重い関係の代数的なDSLです。これを使って、Rubyの中からSQLクエリを最初から書くことができます。 Squeelは、アクティブなレコードクエリのためのより洗練されたDSLであり、SQLリテラルステートメントを使用するほとんどのケースを排除します。