如何在续集中重新加载表模式?

时间:2012-09-05 14:55:09

标签: ruby sequel

鉴于我有以下迁移:

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 => "admin@fancy-startup.example")
    @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

有更好的方法吗?

1 个答案:

答案 0 :(得分:8)

这个hack比你的hack简单得多:(重新)将数据集设置为表名:

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以便它可以正常工作。