2012-07-27 62 views
8

我是一個rails新手,並且正在嘗試使用rails在表上執行搜索,並且我只是使用我的sql知識來完成此操作。但是,這似乎並不像鐵軌或紅寶石甚至...如何在rails中添加條件where子句

有沒有更好的方法來做我在下面做的事情? (基本上,僅傳遞日期參數爲sql如果它們被填充)

def search(begin_date=nil, end_date=nil) 

    subject = " and created_at " 

    if !(begin_date.nil? || end_date.nil?) 
     where_part = subject + "BETWEEN :begin_date AND :end_date" 
    else if (begin_date.nil? && end_date.nil?) 
     where_part = "" 
    else if(begin_date.nil?) 
     where_part = subject + " <= :end_date" 
    else if (end_date.nil?) 
     where_part = subject + " >= :begin_date" 
    end 
    end 
    end 
    end 

    User.joins(places: {containers: {label: :user}}).where("users.id= :user_id "+where_part, user_id: self.id, begin_date:begin_date, end_date:end_date).group(...).select(...) 
end 

EDIT

user.rb

has_many :containers 
has_many :user_places 
has_many :places, through: :user_places 
has_many :labels 

place.rb

has_many :containers 
has_many :user_places 
has_many :users, through: :user_places 

容器。 rb

belongs_to :label 
belongs_to :place 
belongs_to :user 

label.rb

belongs_to :user 
has_many :containers 

基本上,我想要得到的容器內給定用戶的標籤或有直接的關係數的計數,每個位置,並希望能夠對其進行過濾通過開始和結束日期。

這兩個日期中的任何一個可能都是零,所以我需要在我的「查詢」中解決這個問題。

我的問題是:我怎樣才能做到這一點的方式嗎?我看了一下http://guides.rubyonrails.org/active_record_querying.html,也許我可以在這裏使用except命令......但是這個關係模型似乎有點複雜,用ActiveRecord來做到這一點......我怎麼可能?我真的認爲我應該使用ActiveRecord,但怎麼樣?

謝謝

+0

[這裏是如何做一個很好的例子,加入與活動記錄] [1] [1]:http://stackoverflow.com/questions/764538/ruby-on-rails-how -to-join-two-tables – 2012-07-27 15:05:38

+0

嗨,我的問題不在於連接...我只是沒有寫出它們,因爲它們不相關。我的事情是有條件的搜索參數 – MrWater 2012-07-27 15:13:20

+0

@itsalltime - 我想Bob想說的是 - 爲什麼不使用Active Record而不是直接編寫SQL? http://guides.rubyonrails.org/active_record_querying.html – JasCav 2012-07-27 15:16:42

回答

18

可以將多個where調用查詢這樣你就可以建立自己的基本查詢:

query = User.joins(...) 
      .group(...) 
      .select(...) 
      .where('users.id = :user_id', :user_id => self.id) 

,然後添加其他where呼叫根據日期間隔:

​​

每個where調用使用AND添加另一塊到您的整體WHERE子句,如下所示:

q = M.where(a).where(b).where(c) 

與發言WHERE a AND b AND c相同。

+0

嗨,這個答案很好。謝謝。看來我不能使用begin_date .. end_date(並且必須使用空格而不是nil),因爲我從文本字段收集日期時間並在本地轉換它們。 'if!begin_date.blank? begin_date = DateTime.strptime(「#{begin_date} 00:00:00」,「%m /%d /%Y%H:%M:%S」)to_datetime end'我最終使用了您的替代建議:'或where('created_at between:begin_date and:end_date',:begin_date => begin_date,:end_date => end_date)' – MrWater 2012-07-28 17:08:36

+0

@itsalltime:如果'begin_date'和'end_date'是使用'begin_date .. end_date',真正的日期對象,但它似乎是你實際上有字符串,而不是。我建議在使用它們之前將它們轉換爲日期對象,以便您只需在一個地方擔心日期格式問題。 – 2012-07-28 18:53:59

+0

嗨,我轉換他們與上面張貼的功能,但即使如此begin_date .. end_date不起作用,這就是爲什麼我不得不去替代 – MrWater 2012-07-29 22:06:28

0

我想不出一個很大的原因,爲什麼你會真正想要生成SQL代碼中的。主動記錄似乎是一種更有效的解決方案,除非你沒有理由不使用它。

Link explaining how to join tables with active record

+0

我實際上對如何使用連接有一些疑惑,但我想我找到了解決我想要的東西的方法,因爲我張貼在我編輯的答案中。我的事實際上是有條件的搜索參數。 – MrWater 2012-07-27 15:49:16

+0

哦,對於這樣的情況和東西:http://www.rigelgroupllc.com/blog/2014/09/14/working-with-complex-sql-statements/ – Danny 2015-02-27 16:36:23