我的 Rails 应用开始需要复杂的查询。我应该开始使用原始 SQL 查询吗? Rails 社区的趋势是什么?
更新:
我现在没有书面查询,我想在开始之前提出这个问题。但这是我想要做的一个例子:
我有分类的书。我想说-
Give me all books that were:
-created_at (added to store) between date1 and date2
-updated_at before date3
-joined with books that exist in shopping carts right now
我还没有编写查询,但我认为 rails 版本将是这样的:
books_to_consider = Book.find(:all,
:conditions => "created_at <= '#{date2}' AND created_at >= '#{date1}' AND updated_at <= '#{date3}'",
:joins => "as b inner join carts as c on c.book_id = b.id")
我并不是说 ActiveRecord 不能处理这个查询,而是使用原始 SQL 来提高可读性是否更容易被接受(或者可能还有其他我不知道的限制)?
最佳答案
大体思路是坚持ActiveRecord
- 尽可能生成查询,并使用 SQL 片段 仅在必要时 .明确支持 SQL 片段,因为 ActiveRecord
的创建者意识到 SQL 不能完全抽象掉。
使用 find
没有 SQL 片段的方法通常会获得更好的可维护性。鉴于您的示例,请尝试:
Book.find(:all,
:conditions => ["created_at >= ? AND created_at <= ? AND updated_at <= ?",
date1, date2, date3]
:include => :carts)
:inlude => :carts
如果您添加了 has_many :carts
将进行连接给您的 Book
模型。如您所见,不必涉及太多 SQL。甚至输入的引用和转义也可以留给 Rails,同时仍然使用 SQL 文字来处理 >=
和 <=
运营商。再往前走一点,你可以让它更清楚:
class Book < AciveRecord::Base
# Somewhere in your Book model:
named_scope :created_between, lambda { |start_date, end_date|
{ :conditions => { :created_at => start_date..end_date } }
}
named_scope :updated_before, lambda { |date|
{ :conditions => ["updated_at <= ?", date] }
}
# ...
end
Book.created_between(date1, date2).updated_before(date3).find(:all,
:include => :carts)
更新:
named_scope
的点s 当然是重用条件。由您决定将一组条件放入命名范围是否有意义。
关于sql - 我的 Rails 查询开始变得复杂,我应该切换到原始 SQL 查询吗?你做什么工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1008740/