2011-11-16 1 views
0

축구 용구를 만드는 스크립트가 있습니다.Datamapper 할당 동작

각 클럽은 다른 클럽과 단 한 번의 게임을 할 수 있으며 집이나 떨어져있을 수 있습니다.

이 (대신 190의 145 경기를 만드는 것와 클럽 게임 같은 양의 재생되지 않음)

clubs_to_play = all_clubs = Club.all #problematic line 

    all_clubs.each do |club| 
    home = true 
    clubs_to_play.delete(club) 
    clubs_to_play.each do |club_to_play| 
     f = Fixture.new 
     if (home) 
     f.home = club 
     f.away = club_to_play 
     home = false 
     else 
     f.home = club_to_play 
     f.away = club 
     home = true 
     end 
     f.save 
    end 
    end 
end 

을하지만 20 개 클럽 작동하지 않습니다 내 실제 코드는 내가 첫 번째 라인을 변경하는 경우 다음과 같습니다 :

clubs_to_play = Club.all 
all_clubs = Club.all 

스크립트가 작동하고 190 개의 일치 항목이 생성됩니다. 왜 그런가요? 이 작업을 수행 할 때

+0

더 깨끗한 해결책에 대한 내 답변 끝에 편집하십시오. – d11wtq

답변

1

는 :

all_clubs = Club.all 
clubs_to_play = all_clubs 

그들은 당신이 그들의 object_id 보면 당신이 볼 수있는합니다 (같은 객체 다음과 같습니다

clubs_to_play = all_clubs = Club.all 

은 당신이 기본적으로하는 일은 이것이다 에스).

DataMapper는 키커 메서드가 호출 될 때까지 레코드 세트를 구체화하지 않습니다. 기본적으로 iterating을 시작할 때까지 SQL이 실행되지 않습니다. 물론, 이러한 변수 같은 객체에 둘 점, 당신이 all_clubs을 반복 시작할 때 그들은 동일한 개체 때문에, 당신은 모두all_clubsclubs_to_play에서 데이터베이스의 모든 레코드를 당겨입니다. 반대로

,이 작업을 수행 :

all_clubs = Club.all 
clubs_to_play = Club.all 

여기 all_clubsclubs_to_play 참조 다른 개체. 즉, 그들은 object_ids이 다르고 all_clubs을 반복 할 때 모든 레코드가 구체화되지만 clubs_to_play은 반복하고 (다른 모음에서 값을 삭제할 때까지) 영향을받지 않습니다.

알고리즘은 all_clubsclubs_to_play을 서로 독립적으로 수정할 수 있으므로 동일한 개체 일 때 바람직하지 않은 동작을하고 있습니다. 이 (약간 더 많은 기능) 방식과 같은

시도 뭔가 :

Club.all.combination(2).each_with_index do |(club1, club2), idx| 
    Fixture.create(
    :home => idx.even? ? club1 : club2, 
    :away => idx.even? ? club2 : club1 
) 
end 

이 집을 사이의 교대를 유지하기 기술적으로 더 많은 기능 가지 방법이 있습니다,하지만 그들은 더 복잡하다. Enumerable#combination은 컬렉션에서 가능한 모든 (고유 한) 값 조합을 반환합니다.

+0

이것은 대단한 답변입니다! 고맙습니다. 조합 방법에 대해 몰랐습니다. Ruby에서 프로젝트를 시작하고 많은 것을 배우고 있습니다! 감사! – marcosdsanchez