2012-03-14 40 views
3

我正在嘗試使用Arel#提取方法。我在源碼中的test_extract.rb中看到了一個測試用例中的例子,但是當我嘗試在我的應用程序中重現它時,我得到了未定義的方法。在rails中如何使用Arel#extract方法?

table = Arel::Table.new :users 
puts table[:created_at].extract('hour').to_sql 
=> NoMethodError: undefined method `extract' for #<Arel::Attributes::Attribute:0x7..8> 

我使用pg作爲數據庫。

更新:

我的目標是與這一結果在SQL中結束:

SELECT users.* FROM users WHERE EXTRACT(HOUR from users."created_at") = '1' 

我想找到一小時等於創建的所有用戶的任何一天之一。這在SQL中工作,但我想知道如何在AREL中創建它。這是一個example如何在arel測試套件中使用。

+0

我沒有在文檔中看到'#extract'作爲Arel :: Table類的一部分。你想做什麼?從表中檢索「date」? – ScottJShea 2012-03-14 23:32:56

+0

我更新了說明以回答您的問題。 – 2012-03-14 23:46:39

+0

ActiveRecord查詢會對你更好嗎? 'Users.where(「Minute(?)= 1」,:created_at).all'? – ScottJShea 2012-03-15 00:10:31

回答

1

摘錄是節點的方法,您可以將其強制轉換到任何列(如users [:id])上,但不在Arel :: Table實例上。

所以,來構建你的查詢,你需要:

  • 得到阿雷爾::表實例users = Arel::Table.new(:users)或者如果你使用ActiveRecord - 上阿雷爾users = User.arel_table
  • 設置的SELECT語句::與project方法表實例:users = users.project(Arel.sql('*'))
  • 組,其中有where方法聲明:users.where(users[:created_at].extract(:hour).eq(1))

在一個塊:

query = User.arel_table. 
      project(Arel.sql('*')). 
      where(users[:created_at].extract(:hour).eq(1)) 
users = User.find_by_sql(query) 
# => "SELECT * FROM \"users\" WHERE EXTRACT(HOUR FROM \"users\".\"created_at\") = 1" 
0

我不得不上阿雷爾::節點:: NamedFunction,其不暴露所述方法#extract(如阿雷爾6.0)的實例進行的提取物DOW。我設法通過手動創建Arel::Nodes::Extract的實例來實現此目的。這裏是爲我工作,如果任何人有一個類似的問題:

Arel::Nodes::Extract.new( Arel::Nodes::NamedFunction.new('some_function_name', [param1, param2, ...]), :dow )

您可以用ActiveRecord的#where,而不是通過阿雷爾構建完整的查詢亞歷山大Karmes的回答例證直接使用阿雷爾節點。因此,這裏是執行由答案所需的查詢另一種方式:

User.where( Arel::Nodes::Extract.new(User.arel_table[:created_at], :hour).eq(1) )

其中產量:

SELECT "users".* FROM "users" WHERE EXTRACT(HOUR FROM "users"."created_at") = 1

有了你可以保持鏈接在你User模型中定義的其他範圍的額外好處。

相關問題