我有兩個型號:Connection
和Membership
...其間具有以下關聯:如何在關聯的列上執行where子句?
class Membership < ActiveRecord::Base
belongs_to :inviter, class_name: "User", foreign_key: "user_id"
belongs_to :invited, class_name: "User", foreign_key: "invited_id"
has_many :connections, dependent: :destroy
end
class Connection < ActiveRecord::Base
belongs_to :inviter_membership, class_name: "Membership", foreign_key: "membership_id"
belongs_to :invited_membership, class_name: "Membership", foreign_key: "invited_membership_id"
end
這裏有兩個membership
對象:
[34] pry(#<Membership>)> self
=> #<Membership id: 54, family_tree_id: 43, user_id: 41, created_at: "2015-12-01 00:40:37", updated_at: "2015-12-01 00:40:37", relation: "wife", member_id: nil, invited_id: 1, relative_type: 0>
[35] pry(#<Membership>)> mem
=> #<Membership id: 53, family_tree_id: 1, user_id: 1, created_at: "2015-12-01 00:39:58", updated_at: "2015-12-01 00:40:37", relation: "husband", member_id: nil, invited_id: 41, relative_type: 0>
[39] pry(#<Membership>)> self.invited_id
=> 1
然後,我有一個connection
對象:
[36] pry(#<Membership>)> c
=> #<Connection id: 38, membership_id: 53, sent_at: "2015-12-01 00:40:14", responded_at: nil, send_limit: nil, times_sent: 1, removed_at: nil, created_at: "2015-12-01 00:40:14", updated_at: "2015-12-01 00:40:14", request_status: 0, invited_membership_id: nil>
如何查找所有connection
記錄,即有membership.invited_id = 41
(或某些值)?
換句話說,我願做這樣的事情:
Connection.where("membership.invited_id = ? OR invited_membership.invited_id = ?", self.id, self.id).exists?
但是,當我嘗試了上面,我得到這個錯誤:
[138] pry(main)> Connection.where("membership.invited_id = ? OR invited_membership.invited_id = ?", 41, 41).exists?
Connection Exists (165.3ms) SELECT 1 AS one FROM "connections" WHERE (membership.invited_id = 41 OR invited_membership.invited_id = 41) LIMIT 1
PG::UndefinedTable: ERROR: missing FROM-clause entry for table "membership"
LINE 1: SELECT 1 AS one FROM "connections" WHERE (membership.invit...
那麼,如何運行where
查詢以將相關記錄的列與我提供的參數進行匹配?
編輯1
基於美妙建議從@messanjah我幾乎沒有。這是我使用的查詢:
Connection.joins(:inviter_membership, :invited_membership).
where("memberships.invited_id = ? OR invited_memberships_connections.invited_id = ? OR memberships.user_id = ? OR invited_memberships_connections.user_id = ?", self.inviter.try(:id), self.inviter.try(:id), self.invited.try(:id), self.invited.try(:id)).exists?
哪裏self
是這樣的:
[22] pry(#<Membership>)> self
=> #<Membership id: 69, family_tree_id: 49, user_id: 47, created_at: "2015-12-01 04:53:17", updated_at: "2015-12-01 04:53:17", relation: "wife", member_id: nil, invited_id: 1, relative_type: 0>
但是當我運行該查詢,它返回一個空數組或false
:
[14] pry(#<Membership>)> connection_exists
CACHE (0.0ms) SELECT 1 AS one FROM "connections" INNER JOIN "memberships" ON "memberships"."id" = "connections"."membership_id" INNER JOIN "memberships" "invited_memberships_connections" ON "invited_memberships_connections"."id" = "connections"."invited_membership_id" WHERE (memberships.invited_id = 47 OR invited_memberships_connections.invited_id = 47 OR memberships.user_id = 1 OR invited_memberships_connections.user_id = 1) LIMIT 1
=> false
儘管事實上有一個memberships
與這些ID記錄,可以在這裏看到:
[24] pry(#<Membership>)> c
=> #<Connection id: 49, membership_id: 68, sent_at: "2015-12-01 04:52:51", responded_at: nil, send_limit: nil, times_sent: 1, removed_at: nil, created_at: "2015-12-01 04:52:51", updated_at: "2015-12-01 04:52:51", request_status: 0, invited_membership_id: nil>
[25] pry(#<Membership>)> c.inviter_membership
=> #<Membership id: 68, family_tree_id: 1, user_id: 1, created_at: "2015-12-01 04:52:32", updated_at: "2015-12-01 04:53:17", relation: "husband", member_id: nil, invited_id: 47, relative_type: 0>
[26] pry(#<Membership>)> c.invited_membership
=> nil
[27] pry(#<Membership>)> c.inviter_membership.invited_id
=> 47
[28] pry(#<Membership>)> c.inviter_membership.user_id
=> 1
請注意在最後兩個查詢中返回IDs
,但是當傳遞給主查詢時,我運行它返回空。
這可能是什麼原因造成的?
編輯2
這是新的代碼,我想:
Connection.joins("LEFT JOIN memberships inviter_memberships ON inviter_memberships.id = connections.membership_id").
joins("LEFT JOIN memberships invited_memberships ON invited_memberships.id = connections.invited_membership_id").
where("inviter_memberships.invited_id = ? OR invited_memberships.invited_id = ?
OR inviter_memberships.user_id = ? OR invited_memberships.user_id = ?", self.invited.try(:id), self.invited.try(:id), self.inviter.try(:id), self.inviter.try(:id)).exists?
其中self
是:
[15] pry(#<Membership>)> self
=> #<Membership id: 71, family_tree_id: 50, user_id: 48, created_at: "2015-12-01 05:46:00", updated_at: "2015-12-01 05:46:00", relation: "wife", member_id: nil, invited_id: 1, relative_type: 0>
[20] pry(#<Membership>)> self.invited
=> #<User id: 1, email: "[email protected]", encrypted_password: "$2a$10$IQXTVqZmMaUUv4WZlwXze.OTfWki2d2qZEjj01isCZZ...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 7, current_sign_in_at: "2015-09-25 09:35:43", last_sign_in_at: "2015-09-25 01:36:10", current_sign_in_ip: "127.0.0.1", last_sign_in_ip: "192.168.1.106", created_at: "2015-07-25 02:20:15", updated_at: "2015-09-25 09:35:43", first_name: "Marc", confirmation_token: nil, confirmed_at: "2015-07-25 02:20:16", confirmation_sent_at: "2015-07-25 02:20:16", unconfirmed_email: nil, invitation_relation: nil, avatar: "Me-Bio-Pic.jpg", invitation_token: nil, invitation_created_at: nil, invitation_sent_at: nil, invitation_accepted_at: nil, invitation_limit: nil, invited_by_id: nil, invited_by_type: nil, invitations_count: 0, bio: "I am Marc Gayle. I build things and I love my fami...", last_name: "Gayle", gender: 0, birthday: nil>
[21] pry(#<Membership>)> self.inviter
=> #<User id: 48, email: "[email protected]", encrypted_password: "", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: "2015-12-01 05:40:45", updated_at: "2015-12-01 05:40:45", first_name: "Cheyenne-Kari", confirmation_token: nil, confirmed_at: nil, confirmation_sent_at: nil, unconfirmed_email: nil, invitation_relation: "husband", avatar: nil, invitation_token: "D8uPGyxAeX95kfYGxRq-", invitation_created_at: "2015-12-01 05:40:45", invitation_sent_at: "2015-12-01 05:40:45", invitation_accepted_at: nil, invitation_limit: nil, invited_by_id: 1, invited_by_type: "User", invitations_count: 0, bio: nil, last_name: "Gayle", gender: 1, birthday: nil>
基本上什麼,我試圖做的是試圖發現是否存在connection
記錄,用於記錄我將要創建的相關membership
記錄(努力嘗試n ot創建一個重複的connection
記錄)。
換句話說,每個connection
記錄應該對應於inviter_membership
和invited_membership
。
現在,在Membership
模型上的after_create :setup_connection
回調上創建連接。因此,我正在檢查數據庫中的Connection
記錄,該記錄包含相關的membership
型號,然後只更新該記錄,而不是創建新記錄。
所以這就是爲什麼在我的代碼片段的self
,是membership
記錄(因爲我在運行時用撬調試 - 即after_create
調用後,新connection
記錄之前已創建)。
我希望這有助於澄清我正在嘗試做什麼。如果不是,我可以再解釋一些。
編輯3
下面是執行LEFT JOIN
SQL我上面做的服務器日誌:
[1] pry(#<Membership>)> connection_exists
CACHE (0.0ms) SELECT 1 AS one FROM "connections" LEFT JOIN memberships inviter_memberships ON inviter_memberships.id = connections.membership_id LEFT JOIN memberships invited_memberships ON invited_memberships.id = connections.invited_membership_id WHERE (inviter_memberships.invited_id = 1 OR invited_memberships.invited_id = 1
OR inviter_memberships.user_id = 51 OR invited_memberships.user_id = 51) LIMIT 1
=> false
完美...這正是我所期待的。非常感謝! – marcamillion
幾乎完美:) - 查看更新的問題,更詳細地介紹了@messanjah的細節。 – marcamillion
INNER聯盟中的一個可能會拋出你想要的記錄。切換到左連接。 – messanjah