Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何在关联的列上执行where子句?_Ruby On Rails_Ruby On Rails 4_Activerecord - Fatal编程技术网

Ruby on rails 如何在关联的列上执行where子句?

Ruby on rails 如何在关联的列上执行where子句?,ruby-on-rails,ruby-on-rails-4,activerecord,Ruby On Rails,Ruby On Rails 4,Activerecord,我有两个模型:Connection和Membership…它们之间有以下关联: 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

我有两个模型:
Connection
Membership
…它们之间有以下关联:

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
然后我有一个
连接
对象:

[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>
但当我尝试上述方法时,我得到了以下错误:

[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>
尽管有一个带有这些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
其中
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: "abc@test.com", 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: "def@test.com", 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.joins(:inviter_membership, :invited_membership).
  where("memberships.invited_id = ? OR invited_memberships_connections.invited_id = ?", self.id, self.id)
这有点尴尬,因为表别名不明显(我使用的是Rails 4.2.3,YMMV)

您可能希望显式构造联接,以便更好地控制查询:

Connection.
  joins("INNER JOIN memberships inviter_memberships ON inviter_memberships.id = connections.inviter_membership_id").
  joins("INNER JOIN memberships invited_memberships ON invited_memberships.id = connections.invited_membership_id").
  where("inviter_memberships.invited_id = ?
      OR invited_memberships.invited_id = ?", self.id, self.id)
如果关联记录可能不存在(例如,一个连接可能没有受邀的_成员资格),请使用左连接以避免将其抛出

Connection.
  joins("LEFT JOIN memberships inviter_memberships ON inviter_memberships.id = connections.inviter_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 = ?", self.id, self.id)

完美…这正是我想要的。多谢!近乎完美:)--请参阅更新的问题,其中包含更多关于此处出现的问题的详细信息@messanjah。可能是某个内部连接丢弃了您想要的记录。切换到左连接。我实际上使用的是活动记录查询。我还没有试过SQL。在那个版本中是什么引起的?同样的。当使用该语法连接时,ActiveRecord执行内部连接。左联接需要字符串形式。
[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: "abc@test.com", 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: "def@test.com", 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>
[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
Connection.joins(:inviter_membership, :invited_membership).
  where("memberships.invited_id = ? OR invited_memberships_connections.invited_id = ?", self.id, self.id)
Connection.
  joins("INNER JOIN memberships inviter_memberships ON inviter_memberships.id = connections.inviter_membership_id").
  joins("INNER JOIN memberships invited_memberships ON invited_memberships.id = connections.invited_membership_id").
  where("inviter_memberships.invited_id = ?
      OR invited_memberships.invited_id = ?", self.id, self.id)
Connection.
  joins("LEFT JOIN memberships inviter_memberships ON inviter_memberships.id = connections.inviter_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 = ?", self.id, self.id)