2008-11-29 33 views
2
mysql> desc categories; 
+-------+-------------+------+-----+---------+----------------+ 
| Field | Type  | Null | Key | Default | Extra   | 
+-------+-------------+------+-----+---------+----------------+ 
| id | int(11)  | NO | PRI | NULL | auto_increment | 
| name | varchar(80) | YES |  | NULL |    | 
+-------+-------------+------+-----+---------+----------------+ 

mysql> desc expenses; 
+-------------+---------------+------+-----+---------+----------------+ 
| Field  | Type   | Null | Key | Default | Extra   | 
+-------------+---------------+------+-----+---------+----------------+ 
| id   | int(11)  | NO | PRI | NULL | auto_increment | 
| created_at | datetime  | NO |  | NULL |    | 
| description | varchar(100) | NO |  | NULL |    | 
| amount  | decimal(10,2) | NO |  | NULL |    | 
| category_id | int(11)  | NO | MUL | 1  |    | 
+-------------+---------------+------+-----+---------+----------------+ 

現在我需要的前N類這樣的...將DB-ISH查詢轉換爲Rails ActiveRecord模型術語是否有意義?

Expense.find_by_sql("SELECT categories.name, sum(amount) as total_amount 
    from expenses 
    join categories on category_id = categories.id 
    group by category_id 
    order by total_amount desc") 

但是,這在我的Rails的良心嘮叨..它似乎有可能實現通過Expense.find同樣的事情並提供選項,如:組,:連接..

  • 有人可以將此查詢轉換成ActiveRecord模型說話嗎?
  • 這是值得的...我個人覺得SQL更具可讀性,讓我的工作更快完成..也許因爲我仍然在學習Rails。沒有在源代碼中嵌入SQL的任何優勢(除了不能改變DB廠商的SQL風格等)?
  • 似乎find_by_sql沒有像find這樣的綁定變量設置。什麼是解決方法?例如如果我想限制記錄的數量到用戶指定的限制。

回答

2
Expense.find(:all, 
    :select => "categories.name name, sum(amount) total_amount", 
    :joins => "categories on category_id = categories.id", 
    :group => "category_id", 
    :order => "total_amount desc") 

希望有幫助!

2

似乎find_by_sql沒有像find這樣的綁定變量提供。

確實如此。 (從Rails的docs

# You can use the same string replacement techniques as you can with ActiveRecord#find 
    Post.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date] 
1

嗯,這是最終爲我工作的代碼..(弗朗索瓦..生成的SQL語句是缺少了join關鍵字)

def Expense.get_top_n_categories options={} 
    #sQuery = "SELECT categories.name, sum(amount) as total_amount 
    # from expenses 
    # join categories on category_id = categories.id 
    # group by category_id 
    # order by total_amount desc"; 
    #sQuery += " limit #{options[:limit].to_i}" if !options[:limit].nil? 
    #Expense.find_by_sql(sQuery) 
    query_options = {:select => "categories.name name, sum(amount) total_amount", 
     :joins => "inner join categories on category_id = categories.id", 
     :group => "category_id", 
     :order => "total_amount desc"} 
    query_options[:limit] = options[:limit].to_i if !options[:limit].nil? 
    Expense.find(:all, query_options) 
    end 

的find_by_sql確實有軌綁定變量...我不知道我是如何忽略這一點的。 最後是上面使用用戶指定的SQL注入潛在入口點還是to_i方法調用阻止?

感謝您的幫助。我很感激。

相關問題