[英]Rails - Find matches in relation model
Let's say we have these two models: 假设我们有以下两种模型:
class Attendee < ActiveRecord::Base
has_many :dances
has_many :partners, through: :events
end
class Dance < ActiveRecord::Base
belongs_to :attendee
belongs_to :partner, class_name: Attendee
end
I'd like to implement a method, for example Dance.matches_of(attendee)
that returns the dances of an attendee only if his partners have a dance where he is the partner. 我想实现一个方法,例如
Dance.matches_of(attendee)
,该方法仅在参与者的伙伴在伙伴所在的地方跳舞时才返回参与者的舞蹈。 How would you implement an efficient solution? 您将如何实施有效的解决方案?
EDIT: 编辑:
Sorry because I couldn't explain my question well, I'll try to clarify it (I changed the Event
class name to Dance
). 抱歉,因为我无法很好地解释我的问题,因此我将尝试澄清该问题(我将
Event
类的名称更改为Dance
)。 If an user wants to dance with another one, he/she will create an object Dance
, specifying the partner. 如果用户想与另一个人跳舞,他/她将创建一个对象
Dance
,指定伙伴。 So, let's say that Bob would like to dance with Sarah, the database table dances
would look like this (I'll use usernames instead of ids to make it clearer, hopefully): 因此,假设鲍勃想与莎拉共舞,数据库的表
dances
看起来像这样(希望我会使用用户名而不是ID使其更清楚):
| id | attendee_id | partner_id |
---------------------------------------------------
| 1 | bob | sarah |
So, Dance.matches_of(bob)
would return nothing, as there is no one that he wants to dance with who also wants him as a dancing partner (poor Bob). 因此,
Dance.matches_of(bob)
将不返回任何内容,因为没有人愿意与谁跳舞,而谁也希望他作为舞伴(可怜的鲍勃)。 After a while Sarah thinks that maybe Bob is not such a bad guy, and he deserves a chance to hit the floor. 过了一会儿,莎拉认为也许鲍勃不是一个坏人,他应该有机会发言。 Now, the
dances
table looks like this: 现在,
dances
表如下所示:
| id | attendee_id | partner_id |
---------------------------------------------------
| 1 | bob | sarah |
---------------------------------------------------
| 2 | sarah | bob |
Dance.matches_of(bob)
now returns the dance with id 1, because it's the record that shows Bob's interest on dancing with Sarah AND Sarah wants to dance with him as well ( Dance.matches_of(sarah)
would retrieve the second record). Dance.matches_of(bob)
现在返回ID为1的舞蹈,因为这是记录,显示鲍勃有兴趣与Sarah跳舞,并且Sarah也想与他跳舞( Dance.matches_of(sarah)
将检索第二个记录)。 If Bob wanted to dance with Anna too, and so did she, the method would retrieve two records and Bob would be the happiest guy at the party, as he'd have two dancing partners. 如果鲍勃也想和安娜一起跳舞,那么她也一样,该方法将检索两个记录,而鲍勃将是聚会上最快乐的家伙,因为他有两个舞伴。
I hope this explanation is clearer, but I'm aware that if it's so hard to be explained and understood, maybe the approach I'm following is not correct, so I'm open to suggestions. 我希望这个解释更清楚,但是我知道,如果很难解释和理解它,也许我所遵循的方法是不正确的,所以我愿意提出建议。
EDIT 2: 编辑2:
The solution I came up with: 我想出的解决方案:
def self.matches_of(attendee)
attendee.dances.select { |dance| dance.partner.partners.include? attendee }
end
But I don't expect it to be much efficient anyway. 但是我不希望它有任何效率。
Given your models, you can add a matches_of
scope to the Dance model: 给定您的模型,您可以将
matches_of
范围添加到Dance模型:
class Attendee < ActiveRecord::Base
has_many :dances
has_many :partners, class_name: 'Attendee', through: :dances
end
class Dance < ActiveRecord::Base
belongs_to :attendee
belongs_to :partner, class_name: 'Attendee'
scope :matches_of, -> (attendee) {
where(partner_id: attendee.id, attendee_id: attendee.partner_ids)
}
end
Given dances like 像这样跳舞
| id | attendee_id | partner_id |
---------------------------------------------------
| 1 | bob | sarah |
matches_of will return [] matchs_of将返回[]
bob = Attendee.find 1
Dance.matches_of(bob)
# returns []
Given dances like 像这样跳舞
| id | attendee_id | partner_id |
---------------------------------------------------
| 1 | bob | sarah |
---------------------------------------------------
| 2 | sarah | bob |
matches_of will return Dance #2 matchs_of将返回舞蹈#2
Dance.matches_of(bob)
# returns [#<Dance id: 2, attendee_id: 2, partner_id: 1>]
I can think of a method like this, if there is a partner_id
relating to an id
in attendees
table: 我可以想到这样的方法,如果在
attendees
表中有一个与id
有关的partner_id
:
def partner_events
Event.where('partner_id = ? and attendee_id in (?)', id, events.map(&:partner_id))
end
def matches_of(attendee)
partner_ids = Event.pluck(:attendee_id).where(:partern_id = > attendee.id).uniq
Event.where('attendee_id = ? and partner_id in (?)', attendee.id, partner_ids)
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.