方法
執行個體公開方法
async_count_by_sql(sql) 連結
與 #count_by_sql
相同,但非同步執行查詢並傳回 ActiveRecord::承諾
。
async_find_by_sql(sql, binds = [], preparable: nil, allow_retry: false, &block) 連結
與 #find_by_sql
相同,但非同步執行查詢並傳回 ActiveRecord::承諾
。
# File activerecord/lib/active_record/querying.rb, line 59 def async_find_by_sql(sql, binds = [], preparable: nil, allow_retry: false, &block) with_connection do |c| _query_by_sql(c, sql, binds, preparable: preparable, allow_retry: allow_retry, async: true) end.then do |result| _load_from_sql(result, &block) end end
count_by_sql(sql) 連結
傳回 SQL 陳述式的結果,該陳述式應僅包含 SELECT 部分的 COUNT(*)。此方法的使用應限制於使用 ActiveRecord::計算
類別方法無法執行的複雜 SQL 查詢。在使用此方法之前先查看那些方法,因為它可能會將你鎖定在特定資料庫引擎中或需要程式碼變更才能切換資料庫引擎。
Product.count_by_sql "SELECT COUNT(*) FROM sales s, customers c WHERE s.customer_id = c.id"
# => 12
參數
-
sql
- 應從資料庫傳回數量查詢的 SQL 陳述式,請參閱上述範例。
find_by_sql(sql, binds = [], preparable: nil, allow_retry: false, &block) 連結
針對資料庫執行自訂的 SQL 查詢,並傳回所有結果。結果將以陣列形式傳回,請求的欄位封裝在你從中呼叫此方法的模型的屬性中。例如,如果你呼叫 Product.find_by_sql
,則結果將在 Product
物件中傳回,其屬性為你在 SQL 查詢中指定的屬性。
如果你呼叫跨越多個資料表的複雜 SQL 查詢,則 SELECT 指定的欄位將是模型屬性,無論它們是否為對應資料表的欄位。
sql
參數是字串形式的完整 SQL 查詢。它會如實呼叫;不會執行資料庫獨立的轉換。由於使用特定於資料庫的術語會將你鎖定在使用該特定資料庫引擎中,或在切換引擎時需要變更呼叫,因此這應該是最後的手段。
# A simple SQL query spanning multiple tables
Post.find_by_sql "SELECT p.title, c.author FROM posts p, comments c WHERE p.id = c.post_id"
# => [#<Post:0x36bff9c @attributes={"title"=>"Ruby Meetup", "author"=>"Quentin"}>, ...]
你可以使用與 ActiveRecord::查詢方法#where
相同的字串替換技巧
Post.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date]
Post.find_by_sql ["SELECT body FROM comments WHERE author = :user_id OR approved_by = :user_id", { :user_id => user_id }]
請注意,從使用者輸入中建立你自己的 SQL 查詢字串可能會使你的應用程式接觸到插入攻擊 (guides.rubyonrails.org/security.html#sql-injection).
# File activerecord/lib/active_record/querying.rb, line 51 def find_by_sql(sql, binds = [], preparable: nil, allow_retry: false, &block) result = with_connection do |c| _query_by_sql(c, sql, binds, preparable: preparable, allow_retry: allow_retry) end _load_from_sql(result, &block) end