{"action":"created","comment":{"url":"https://api.github.com/repos/cubing/worldcubeassociation.org/pulls/comments/67508353","id":67508353,"diff_hunk":"@@ -13,7 +15,25 @@ def current_member?\n   validate :start_date_must_be_earlier_than_end_date\n   def start_date_must_be_earlier_than_end_date\n     if start_date && end_date && start_date >= end_date\n-      errors.add(:start_date, \"must be earlier than end_date\")\n+      errors.add(:start_date, \"must be earlier than end date\")\n+    end\n+  end\n+\n+  validate :membership_periods_cannot_overlap_for_single_user\n+  def membership_periods_cannot_overlap_for_single_user\n+    if (start_date)\n+      new_period = start_date..(end_date || Date::Infinity.new)\n+      if self.id\n+       team_members = TeamMember.where(\"user_id = :user_id and team_id = :team_id and id <> :team_member_id\", {user_id: self.user_id, team_id: self.team_id, team_member_id: self.id})\n+      else\n+       team_members = TeamMember.where(\"user_id = :user_id and team_id = :team_id\", {user_id: self.user_id, team_id: self.team_id})\n+      end\n+      team_members.each do |team_member|\n+        existing_period = team_member.start_date..(team_member.end_date || Date::Infinity.new)\n+        if new_period.overlaps? existing_period\n+          errors.add(:user_id, \"must not have overlapping membership dates with the #{self.team.name}.\")\n+        end\n+      end\n     end","path":"WcaOnRails/app/models/team_member.rb","position":33,"original_position":33,"commit_id":"3d852accfdcb2a3eef6939a401eca2b5e7b0598e","original_commit_id":"3d852accfdcb2a3eef6939a401eca2b5e7b0598e","user":{"login":"jonatanklosko","id":17034772,"avatar_url":"https://avatars.githubusercontent.com/u/17034772?v=3","gravatar_id":"","url":"https://api.github.com/users/jonatanklosko","html_url":"https://github.com/jonatanklosko","followers_url":"https://api.github.com/users/jonatanklosko/followers","following_url":"https://api.github.com/users/jonatanklosko/following{/other_user}","gists_url":"https://api.github.com/users/jonatanklosko/gists{/gist_id}","starred_url":"https://api.github.com/users/jonatanklosko/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jonatanklosko/subscriptions","organizations_url":"https://api.github.com/users/jonatanklosko/orgs","repos_url":"https://api.github.com/users/jonatanklosko/repos","events_url":"https://api.github.com/users/jonatanklosko/events{/privacy}","received_events_url":"https://api.github.com/users/jonatanklosko/received_events","type":"User","site_admin":false},"body":"I was under assumption that there may be many new team members at once (this was possible before). Nice that this can be simplified now. I'd change it a bit:\r\n```ruby\r\ndef membership_periods_cannot_overlap_for_single_user\r\n  if start_date\r\n    self_period = start_date..(end_date || Date::Infinity.new)\r\n    other_members = team.team_members.where(user_id: user_id).where.not(id: id)\r\n  \r\n    other_members.each do |team_member|\r\n      other_period = team_member.start_date..(team_member.end_date || Date::Infinity.new)\r\n      if self_period.overlaps? other_period\r\n          errors.add(:user_id, \"must not have overlapping membership dates within #{self.team.name}.\")\r\n      end\r\n    end\r\n  end\r\nend\r\n```\r\nNote that even if the id is nil this evaluates to `where.not(id: nil)` which should work.","created_at":"2016-06-17T13:19:31Z","updated_at":"2016-06-17T13:19:31Z","html_url":"https://github.com/cubing/worldcubeassociation.org/pull/725#discussion_r67508353","pull_request_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/pulls/725","_links":{"self":{"href":"https://api.github.com/repos/cubing/worldcubeassociation.org/pulls/comments/67508353"},"html":{"href":"https://github.com/cubing/worldcubeassociation.org/pull/725#discussion_r67508353"},"pull_request":{"href":"https://api.github.com/repos/cubing/worldcubeassociation.org/pulls/725"}}},"pull_request":{"url":"https://api.github.com/repos/cubing/worldcubeassociation.org/pulls/725","id":74012633,"html_url":"https://github.com/cubing/worldcubeassociation.org/pull/725","diff_url":"https://github.com/cubing/worldcubeassociation.org/pull/725.diff","patch_url":"https://github.com/cubing/worldcubeassociation.org/pull/725.patch","issue_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/issues/725","number":725,"state":"open","locked":false,"title":"Expanded teams table to handle delegates - Fixes #680","user":{"login":"pingskills","id":4403168,"avatar_url":"https://avatars.githubusercontent.com/u/4403168?v=3","gravatar_id":"","url":"https://api.github.com/users/pingskills","html_url":"https://github.com/pingskills","followers_url":"https://api.github.com/users/pingskills/followers","following_url":"https://api.github.com/users/pingskills/following{/other_user}","gists_url":"https://api.github.com/users/pingskills/gists{/gist_id}","starred_url":"https://api.github.com/users/pingskills/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pingskills/subscriptions","organizations_url":"https://api.github.com/users/pingskills/orgs","repos_url":"https://api.github.com/users/pingskills/repos","events_url":"https://api.github.com/users/pingskills/events{/privacy}","received_events_url":"https://api.github.com/users/pingskills/received_events","type":"User","site_admin":false},"body":"The new structure has committees, each committee can have\r\nmultiple teams, and each team has multiple team members.\r\n\r\nCommittees have committee positions which are assigned to\r\nteam members. There is a team leader flag on each committee position.\r\n\r\nFor delegates each senior delegate has their own team. The\r\ndelegate committee is the only committee initially set up\r\nwith multiple teams but I could see the software team using\r\nmultiple teams in the future.\r\n\r\nThis was a much bigger change than I had anticipated :) I'd love to hear your thoughts. Is this something to consider implementing or is it far too complex?","created_at":"2016-06-16T02:12:39Z","updated_at":"2016-06-17T13:19:31Z","closed_at":null,"merged_at":null,"merge_commit_sha":"d4c1ad87c5630eb59033a7639b37d008d6c56494","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/pulls/725/commits","review_comments_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/pulls/725/comments","review_comment_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/pulls/comments{/number}","comments_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/issues/725/comments","statuses_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/statuses/3d852accfdcb2a3eef6939a401eca2b5e7b0598e","head":{"label":"pingskills:teams680","ref":"teams680","sha":"3d852accfdcb2a3eef6939a401eca2b5e7b0598e","user":{"login":"pingskills","id":4403168,"avatar_url":"https://avatars.githubusercontent.com/u/4403168?v=3","gravatar_id":"","url":"https://api.github.com/users/pingskills","html_url":"https://github.com/pingskills","followers_url":"https://api.github.com/users/pingskills/followers","following_url":"https://api.github.com/users/pingskills/following{/other_user}","gists_url":"https://api.github.com/users/pingskills/gists{/gist_id}","starred_url":"https://api.github.com/users/pingskills/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pingskills/subscriptions","organizations_url":"https://api.github.com/users/pingskills/orgs","repos_url":"https://api.github.com/users/pingskills/repos","events_url":"https://api.github.com/users/pingskills/events{/privacy}","received_events_url":"https://api.github.com/users/pingskills/received_events","type":"User","site_admin":false},"repo":{"id":56292449,"name":"worldcubeassociation.org","full_name":"pingskills/worldcubeassociation.org","owner":{"login":"pingskills","id":4403168,"avatar_url":"https://avatars.githubusercontent.com/u/4403168?v=3","gravatar_id":"","url":"https://api.github.com/users/pingskills","html_url":"https://github.com/pingskills","followers_url":"https://api.github.com/users/pingskills/followers","following_url":"https://api.github.com/users/pingskills/following{/other_user}","gists_url":"https://api.github.com/users/pingskills/gists{/gist_id}","starred_url":"https://api.github.com/users/pingskills/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pingskills/subscriptions","organizations_url":"https://api.github.com/users/pingskills/orgs","repos_url":"https://api.github.com/users/pingskills/repos","events_url":"https://api.github.com/users/pingskills/events{/privacy}","received_events_url":"https://api.github.com/users/pingskills/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/pingskills/worldcubeassociation.org","description":"[WCA Project] All of the code that runs on worldcubeassociation.org","fork":true,"url":"https://api.github.com/repos/pingskills/worldcubeassociation.org","forks_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/forks","keys_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/keys{/key_id}","collaborators_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/teams","hooks_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/hooks","issue_events_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/issues/events{/number}","events_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/events","assignees_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/assignees{/user}","branches_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/branches{/branch}","tags_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/tags","blobs_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/git/refs{/sha}","trees_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/git/trees{/sha}","statuses_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/statuses/{sha}","languages_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/languages","stargazers_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/stargazers","contributors_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/contributors","subscribers_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/subscribers","subscription_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/subscription","commits_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/commits{/sha}","git_commits_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/git/commits{/sha}","comments_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/comments{/number}","issue_comment_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/issues/comments{/number}","contents_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/contents/{+path}","compare_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/compare/{base}...{head}","merges_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/merges","archive_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/downloads","issues_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/issues{/number}","pulls_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/pulls{/number}","milestones_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/milestones{/number}","notifications_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/labels{/name}","releases_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/releases{/id}","deployments_url":"https://api.github.com/repos/pingskills/worldcubeassociation.org/deployments","created_at":"2016-04-15T05:05:13Z","updated_at":"2016-04-15T05:05:21Z","pushed_at":"2016-06-16T02:17:07Z","git_url":"git://github.com/pingskills/worldcubeassociation.org.git","ssh_url":"git@github.com:pingskills/worldcubeassociation.org.git","clone_url":"https://github.com/pingskills/worldcubeassociation.org.git","svn_url":"https://github.com/pingskills/worldcubeassociation.org","homepage":"https://www.worldcubeassociation.org/","size":55322,"stargazers_count":0,"watchers_count":0,"language":"PHP","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"cubing:master","ref":"master","sha":"62663fe5aca7d72261445751ff8dd46fa88711ee","user":{"login":"cubing","id":1092267,"avatar_url":"https://avatars.githubusercontent.com/u/1092267?v=3","gravatar_id":"","url":"https://api.github.com/users/cubing","html_url":"https://github.com/cubing","followers_url":"https://api.github.com/users/cubing/followers","following_url":"https://api.github.com/users/cubing/following{/other_user}","gists_url":"https://api.github.com/users/cubing/gists{/gist_id}","starred_url":"https://api.github.com/users/cubing/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cubing/subscriptions","organizations_url":"https://api.github.com/users/cubing/orgs","repos_url":"https://api.github.com/users/cubing/repos","events_url":"https://api.github.com/users/cubing/events{/privacy}","received_events_url":"https://api.github.com/users/cubing/received_events","type":"Organization","site_admin":false},"repo":{"id":34161579,"name":"worldcubeassociation.org","full_name":"cubing/worldcubeassociation.org","owner":{"login":"cubing","id":1092267,"avatar_url":"https://avatars.githubusercontent.com/u/1092267?v=3","gravatar_id":"","url":"https://api.github.com/users/cubing","html_url":"https://github.com/cubing","followers_url":"https://api.github.com/users/cubing/followers","following_url":"https://api.github.com/users/cubing/following{/other_user}","gists_url":"https://api.github.com/users/cubing/gists{/gist_id}","starred_url":"https://api.github.com/users/cubing/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cubing/subscriptions","organizations_url":"https://api.github.com/users/cubing/orgs","repos_url":"https://api.github.com/users/cubing/repos","events_url":"https://api.github.com/users/cubing/events{/privacy}","received_events_url":"https://api.github.com/users/cubing/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/cubing/worldcubeassociation.org","description":"[WCA Project] All of the code that runs on worldcubeassociation.org","fork":false,"url":"https://api.github.com/repos/cubing/worldcubeassociation.org","forks_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/forks","keys_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/keys{/key_id}","collaborators_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/teams","hooks_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/hooks","issue_events_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/issues/events{/number}","events_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/events","assignees_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/assignees{/user}","branches_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/branches{/branch}","tags_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/tags","blobs_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/git/refs{/sha}","trees_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/git/trees{/sha}","statuses_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/statuses/{sha}","languages_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/languages","stargazers_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/stargazers","contributors_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/contributors","subscribers_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/subscribers","subscription_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/subscription","commits_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/commits{/sha}","git_commits_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/git/commits{/sha}","comments_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/comments{/number}","issue_comment_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/issues/comments{/number}","contents_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/contents/{+path}","compare_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/compare/{base}...{head}","merges_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/merges","archive_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/downloads","issues_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/issues{/number}","pulls_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/pulls{/number}","milestones_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/milestones{/number}","notifications_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/labels{/name}","releases_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/releases{/id}","deployments_url":"https://api.github.com/repos/cubing/worldcubeassociation.org/deployments","created_at":"2015-04-18T10:21:53Z","updated_at":"2016-06-15T17:52:51Z","pushed_at":"2016-06-16T22:19:27Z","git_url":"git://github.com/cubing/worldcubeassociation.org.git","ssh_url":"git@github.com:cubing/worldcubeassociation.org.git","clone_url":"https://github.com/cubing/worldcubeassociation.org.git","svn_url":"https://github.com/cubing/worldcubeassociation.org","homepage":"https://www.worldcubeassociation.org/","size":55552,"stargazers_count":14,"watchers_count":14,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":28,"mirror_url":null,"open_issues_count":153,"forks":28,"open_issues":153,"watchers":14,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/cubing/worldcubeassociation.org/pulls/725"},"html":{"href":"https://github.com/cubing/worldcubeassociation.org/pull/725"},"issue":{"href":"https://api.github.com/repos/cubing/worldcubeassociation.org/issues/725"},"comments":{"href":"https://api.github.com/repos/cubing/worldcubeassociation.org/issues/725/comments"},"review_comments":{"href":"https://api.github.com/repos/cubing/worldcubeassociation.org/pulls/725/comments"},"review_comment":{"href":"https://api.github.com/repos/cubing/worldcubeassociation.org/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/cubing/worldcubeassociation.org/pulls/725/commits"},"statuses":{"href":"https://api.github.com/repos/cubing/worldcubeassociation.org/statuses/3d852accfdcb2a3eef6939a401eca2b5e7b0598e"}}}}
{"actor":{"display_login":"jonatanklosko"}}