开发者

Rails, How to determine if a Nested Record Set Exists

I have the following two models:

Project, has_many ProjectParticipants
ProjectParticipants, belongs_to Project

How can I request to determine given these 5 ProjectParticipants, do they belong to a Project?

Also, it should be strictly t开发者_如何学Chose 5, not more or less.

Any thoughts on how to elegantly solve for this type of count?


Assuming participants contain the 5 participants you want to check.

participants.all? {|o| o.project }

This will return true of all participants have a project, otherwise false.

To return the project that was found you can do:

And to see if all participants have the same project:

first_participant = participants.shift

participants.all? {|o| o.project == first_participant.project} unless first_participant.nil?

The good thing about this method is that it short circuits if one of the participant's doesn't have the same project(more efficient).

Edit:

To return the project that they all share, you can do:

first_participant = participants.shift

project_shared = participants.all? {|o| o.project == first_participant.project} and first_particpant.project unless first_participant.nil?

project_shared will be set to the project that they are all share, otherwise it will be to nil/false.

So you can then do:

if project_shared
  # do work
else
 # they dont share a project!
end


You can compare the properties of the ProjectParticipant records in a group:

participants.length == 5 and participants.all? { |p| p.project_id == project.id }

This validates that your array of participants contains five entries and that all of them have the same project_id assigned. Comparing p.project == project will have the side-effect of loading the same Project five times.

To check if they simply belong to a project, you can do this:

participants.length == 5 and participants.all? { |p| p.project_id? }

That project may be deleted and the reference could be invalid, so you may need to resort to actually fetching it:

participants.length == 5 and participants.all? { |p| p.project }

You can also use the group_by method to see if there's only one project involved:

grouped = participants.group_by(&:project)
!grouped[nil] and grouped.length == 1 and grouped.first[1].length == 5

The group_by method will organize the given array into a hash where the key is specified as a parameter and the value is a list of objects matching. It can be handy for situations like this.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜