【发布时间】:2012-03-27 18:40:33
【问题描述】:
对于来自非 ActiveRecord 环境的人来说,复杂的查询具有挑战性。我非常了解编写 SQL 的方式,但是我很难弄清楚如何仅在 AREL 中实现某些查询。我试着自己弄清楚下面的例子,但我似乎找不到正确的答案。
以下是为什么我会选择 AREL 方式而不是我目前的 find_by_sql-way 的一些原因:
- 我的模型中的代码更简洁。
- 更简单的代码(当此查询因链接而与分页结合使用时。)
- 更多的多数据库兼容性(例如,我习惯于
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 来编写类似的东西(出于前面提到的原因),但我就是无法理解上述非基本示例。
仅供参考,我并不是真的在寻找将这些方法直接转换为 AREL,欢迎任何有关解决方案的方向或见解。 如果您认为这是使用 sql-finder 编写这些查询的完全可以接受的解决方案,请再说明一下,请分享您的想法。
注意:如果我需要提供更多示例,请说出来,我会:)
【问题讨论】:
标签: sql ruby-on-rails-3 activerecord associations arel