Ton*_*ony 7 sql activerecord ruby-on-rails
我的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
Run Code Online (Sandbox Code Playgroud)
我还没有编写查询,但我认为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")
Run Code Online (Sandbox Code Playgroud)
我并不是说ActiveRecord无法处理这个查询,但是为了便于阅读(或者还有其他我还不知道的限制),是否更容易接受原始SQL?
mol*_*olf 13
一般的想法是尽可能地坚持ActiveRecord生成的查询,并且只在必要时使用SQL片段.显式支持SQL片段,因为创建者ActiveRecord意识到SQL无法完全抽象掉.
使用find没有SQL片段的方法通常会获得更好的可维护性.举个例子,试试:
Book.find(:all,
:conditions => ["created_at >= ? AND created_at <= ? AND updated_at <= ?",
date1, date2, date3]
:include => :carts)
Run Code Online (Sandbox Code Playgroud)
: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)
Run Code Online (Sandbox Code Playgroud)
更新:该点named_scopes是,当然是为了再利用的条件.由您决定是否将一组条件放入命名范围是否有意义.