2012-09-05 3 views
4

나는 다음과 같은 마이그레이션이 주어 :테이블 스키마를 후속 작업으로 어떻게 다시로드 할 수 있습니까?

Sequel.migration do 
    up do 
    alter_table :users do 
     add_column :is_admin, :default => false 
    end 

    # Sequel runs a DESCRIBE table statement, when the model is loaded. 
    # At this point, it does not know that users have a is_admin flag. 
    # So it fails. 

    @user = User.find(:email => "[email protected]") 
    @user.is_admin = true 
    @user.save! 
    end 
end 

그런 다음 속편이 자동으로 테이블 구조를 다시로드하지 않습니다 (주석 인라인 참조).

나는 그것을 해결하기 위해이 추한 해킹을 사용하고 있습니다 :

# deep magic begins here. If you remove a single line, it will 
# break the migration. 

User.db.schema("users", :reload => true) 
User.instance_variable_set(:@db_schema, nil) 
User.columns 
User.new.respond_to?(:is_admin=) 
sleep 1 

는 더 좋은 방법이 있나요?

답변

6

당신의 해킹보다 훨씬 더 간단이 해킹 :

User.set_dataset :users 

행동에서 볼 : (재) 테이블 이름에 데이터 집합을 설정

require 'sequel' 
DB = Sequel.sqlite 
DB.create_table :users do 
    primary_key :id 
    String :name 
end 

class User < Sequel::Model; end 
User << { name:"Bob" } 

DB.alter_table :users do 
    add_column :is_admin, :boolean, default:false 
end 

p User.first  #=> #<User @values={:id=>1, :name=>"Bob", :is_admin=>false}> 

p User.setter_methods #=> ["name="] 
User.set_dataset :users # Make the magic happen 
p User.setter_methods #=> ["name=", "is_admin="] 

@user = User.first 
@user.is_admin = true 
@user.save 

p User.first  #=> #<User @values={:id=>1, :name=>"Bob", :is_admin=>true}> 

there is no Sequel::Model#save! method 그; 나는 그것이 작동 할 수 있도록 save으로 바 꾸었습니다.

+0

감사합니다! 덧붙여서 : 나는'save! '를 내 버전의 속편에 추가하는 원숭이 패치를 썼다.'save'는 true와 false를 반환한다. 그래서 그것은 나를 위해 작동 :) – iblue