2015-06-30 44 views
0

我希望能夠編寫一個查詢來查找用戶創建,查看或接收的所有消息。如何通過has_many,has_many:through和HABTM加入?

這是我的User類的簡化版本:

class User < ActiveRecord::Base 
    # user_id 
    has_many :messages 

    # message_viewer_id 
    has_many :message_views, foreign_key: 'message_viewer_id' 
    has_many :viewed_messages, through: :message_views 

    # user_id 
    has_and_belongs_to_many :received_messages, 
          join_table: 'messages_recipients', 
          class_name: 'Message' 
end 

我已經試過像PG::UndefinedTable: ERROR: missing FROM-clause entry for table "received_messages"

User. 
    joins(:messages, 
     :message_views, 
     :received_messages). 
    where({messages: {user_id: id}, 
     message_views: {message_viewer_id: id}, 
     received_messages: {user_id: id}}) 

(我下面用.where.conditions,但不斷收到錯誤的許多變化可以加入:messages:message_views沒有問題,但是當我介紹:received_messages時查詢會中斷(是的,我知道我不應該使用HABTM。))

實現此目的最簡單和/或最有效的方法是什麼?

+0

從'has_and_belongs_to_many'切換到'has_many ...,:through'並不難。既然你已經在使用一個自定義表,只要它有一個主鍵「id」列,你可以很容易地重新定義它。如果它缺少該列,那麼使用'ALTER TABLE'很容易添加。 Rails 4.1和更早版本中的'has_and_belongs_to_many'實現留下了很多*。 – tadman

+0

謝謝,@tadman,但我想盡可能避免更改DB結構。如果我找不到一個可行的替代方案,我可能會考慮這一點。 – pdoherty926

+0

我認爲ActiveRecord 4.2將'has_and_belongs_to_many'實現替換爲[AdequateRecord](http://tenderlovemaking.com/2014/02/19/adequaterecord-pro-like-activerecord.html)更新的一部分,但是您會有進行測試以確認。值得一試的是,如果模式改變並轉換爲一流的模式,可以解決任何問題,短期的痛苦,因爲解決方法總是很麻煩。 – tadman

回答

1

嘗試這樣:

class User < ActiveRecord::Base 
    ... 
    def all_messages 
     Message.where("user_id = ? OR id IN (SELECT message_id FROM message_views WHERE message_viewer_id = ?) OR id IN (SELECT message_id FROM messages_recipients WHERE user_id = ?)", self.id, self.id, self.id) 
    end 
    ... 
end 

我建議把指標上user_id上的消息,message_viewer_id上message_views,並user_id上messages_recipients,如果您還沒有。

+0

我馬上試試這個。謝謝! – pdoherty926

+0

我不得不調整其中一個外鍵列名稱,但這確實有效。謝謝! – pdoherty926