2014-10-01 3 views
1

레일 4.0.4로 마이그레이션, 루비 2.1.2레일 4 업데이트 유형 단일 테이블 상속

내가 지금처럼 STI를 사용하려면 :

User < ActiveRecord::Base 
Admin < User 

을하지만 현재 내가 가진 :

User < ActiveRecord::Base 
Info < ActiveRecord::Base 

그래서 모델을 변경 한 다음 마이그레이션을 시작합니다. 내 이전에, 내가 먼저 STI 할 수 있도록 열을 추가 :

add_column :users, :type, :string 

가 그럼 난

# Place I'm currently stuck 

그럼 난에 내 모든 정보 기록을 이동 관리자로 데이터베이스에 현재 사용자를 업데이트 할 사용자 표

Info.all.each { |info| User.create(name: info.name, email: info.email) } 

이전 사용자를 관리자로 변경하는 것 외에는 모두 효과가있는 것 같습니다.

# Seems to work, but doesn't actually save type value 
User.each do |user| 
    user.becomes!(Admin) 
    user.save! # evaluates to true, doesn't have any errors 
end 

# Seems to work, but doesn't actually save type value 
# I've also tried a combo of this one and the above one 
User.each do |user| 
    user.type = "Admin" 
    user.save! # evaluates to true, doesn't have any errors 
end 

User.each do |user| 
    user = user.becomes!(Admin) 
    user.save! # evaluates to true, doesn't have any errors 
end 

# Seems to work, but doesn't actually save type value 
User.each do |user| 
    user.update_attributes(type: "Admin") 
end 

로컬 사용자 변수가 올바른 유형 ("관리자")을 갖고있는 것 같아요마다 함께 true로 평가 저장,하지만 난 Admin.count를 확인하거나 확인 사용자 입력 : 여기에 내가 시도한 몇 가지 있습니다 값은 항상 nil입니다. 나는 당신이 그들을 변경 해야하는 건 아니지만, 이것은 STI로 데이터를 마이그레이션하는 것입니다. 그리고 나서 적절한 클래스로 사용자 또는 관리자를 생성 할 수 있습니다.

적어도 레일스는 오류를 발생시켜야한다고 생각합니다. 오류를 설정하거나 어떻게하면 개발자가 저장 호출에 실패했는지 알 수 있습니다.

+0

주의 사항 : 모델을 참조하지 않고 한 번에 모든 행을 업데이트 할

한 가지 방법은 이전의 원시 SQL을 사용하는 것입니다. 개체를 다시로드하면 해당 사용자에 대한 새 클래스가 표시됩니다. – Nobita

+0

'User.where (...)'와'Admin.all'을 수행하고 업데이트 전에했던 것과 동일한 결과를 얻었습니다. –

답변

1

거기에있다 사용자.

일반적으로 한 SQL 호출에서이 작업을 수행하려면 User.update_all(field: value)을 사용할 수 있지만이 문제를 피할 수있는 또 다른 이유가 있습니다. User 모델을 나중에 제거하면 더 이상 마이그레이션이 실행되지 않습니다. 메모리 내 객체가 여전히 이전 클래스 될 것

def up 
    execute "UPDATE users SET type = 'Admin' WHERE type IS NULL" 
end 
+0

이 모든 객체를 인스턴스화하는 것보다 훨씬 낫다는 것에 동의하십시오. –

3

update_attributes이 유형에 맞지 않지만 (아직 조사한 이유가 없음), update_column이 작동합니다.

User.each do |user| 
    user.update_columns(type: "Admin") 
end 

이 작동하는 이유 및 기타 업데이트는 아마 콜백 또는 실행되지 않는 검증 중 하나를 다시 추적 할 수 없습니다 :

그래서 마이그레이션이 간단하게됩니다. 나는 그것을 방해하는 어떤 콜백이 없다, 그러나 각각에 대한 SQL 호출을 당신이 User.each가 매우 느려질 것입니다 데이터베이스에 더 많은 행이 있다면 아마도 기본 레일의 사람은 type

http://apidock.com/rails/ActiveRecord/Persistence/update_columns

관련 문제