2016-12-07 6 views
2

현재 작은 프로젝트에서 작업 중이며 데이터베이스를 더 빨리 시드하려고합니다. "grand_total_points"라는 새 열을 내 사용자 테이블로 마이그레이션했습니다. 그래서 원래는이 코드를 사용하고있었습니다.update_all을 어떻게 사용하나요? 더 좋은 방법이 있습니까?

user = User.all 
user.each do |x| 
    x.grand_total_points = x.total_points 
    x.save! 
end 

백만 레코드를 업데이트해야하므로 오래 걸립니다. Total_points는 제출 된 모든 사용자 지점을 계산하는 사용자 모델에 이미 정의되어 있습니다. 내 설명을 용서해 줘. update_all 메소드를 사용할 수있는 방법이 있습니까? 가능

답변

2

네는 :

UPDATE "users" SET "grand_total_points" = 'total_points' 

total_points 경우는 열하지만 인스턴스 방법이 아닙니다 update_all 쿼리에 논리를 이동 :

User.update_all('grand_total_points = total_points') 

그것은 다음과 같은 SQL 쿼리를 생성합니다.

User.update_all("grand_total_points = #{total_points calculation translated into SQL terms}") 
+0

'total_points'는 각 사용자마다 다르므로 모든 사용자에 대해 'total_points'가 동일한 경우에만 사용할 수 있습니다. – Thanh

+0

@ThanhHuynh 그것은 오타였습니다.'total_points' (': total_points') 전에 콜론이 있어야했습니다. –

+0

시도했지만 작동하지 않습니다. 이 코드는 모든 사용자의'grand_total_points' 컬럼을'total_points' 문자열로 갱신합니다. – Thanh

0

나는 뭔가를 발견했습니다. 그래서 기본적으로 루비 코드와 실행 SQL 문을 결합하고 그것을 마이그레이션 파일에 넣습니다. 코드 작동 방식은 다음과 같습니다. 이게 도움이 되길 바란다. 데이터에 따라 쿼리를 수행하는지 확인하십시오.

class ChangeStuff < ActiveRecord::Migration 
    def change 
    points = Point.select('user_id, SUM(value) AS value').group(:user_id) 
    points.each do |point| 
    execute "UPDATE users SET grand_total_points = #{point.value} WHERE users.id = #{point.user_id}" 
    end 
    end 
end 

그런 다음 번들 exec rake db : migrate를 실행해야합니다. 정상적인 방법은 2 ~ 3 시간이 걸립니다. 이것은 단지 2 분을 필요로했다.