gpt4 book ai didi

ruby-on-rails - 将更新逻辑放入您的迁移中

转载 作者:行者123 更新时间:2023-12-04 16:02:36 25 4
gpt4 key购买 nike

有几次我遇到过这样的情况,我想重构一些模型的设计,最终将更新逻辑放在迁移中。但是,据我所知,这不是一个好的做法(特别是因为我们鼓励您使用架构文件进行部署,而不是迁移)。你是如何处理这些问题的?

为了阐明我的意思,假设我有一个 User 模型。由于我认为只有两种用户,即“普通”用户和管理员,我选择使用一个简单的 bool 字段来告诉用户是否是管理员。

然而,在我认为我需要第三类用户之后,也许是版主或类似的东西。在这种情况下,我添加了一个 UserType 模型(和相应的迁移),以及第二次迁移以从用户表中删除“admin”标志。问题来了。在“add_user_type_to_users”迁移中,我必须将管理标志值映射到用户类型。此外,为了做到这一点,用户类型必须存在,这意味着我不能使用种子文件,而是在迁移中创建用户类型(也被认为是不好的做法)。下面是一些代表这种情况的虚构代码:

class CreateUserTypes < ActiveRecord::Migration
def self.up
create_table :user_types do |t|
t.string :name, :nil => false, :unique => true
end

#Create basic types (can not put in seed, because of future migration dependency)
UserType.create!(:name => "BASIC")
UserType.create!(:name => "MODERATOR")
UserType.create!(:name => "ADMINISTRATOR")
end

def self.down
drop_table :user_types
end
end

class AddTypeIdToUsers < ActiveRecord::Migration
def self.up
add_column :users, :type_id, :integer

#Determine type via the admin flag
basic = UserType.find_by_name("BASIC")
admin = UserType.find_by_name("ADMINISTRATOR")
User.all.each {|u| u.update_attribute(:type_id, (u.admin?) ? admin.id : basic.id)}

#Remove the admin flag
remove_column :users, :admin

#Add foreign key
execute "alter table users add constraint fk_user_type_id
foreign key (type_id) references user_types (id)"
end

def self.down
#Re-add the admin flag
add_column :users, :admin, :boolean, :default => false

#Reset the admin flag (this is the problematic update code)
admin = UserType.find_by_name("ADMINISTRATOR")

execute "update users set admin=true where type_id=#{admin.id}"

#Remove foreign key constraint
execute "alter table users drop foreign key fk_user_type_id"

#Drop the type_id column
remove_column :users, :type_id
end
end

如您所见,有两个有问题的部分。首先是第一个模型中的行创建部分,如果我想连续运行所有迁移,这是必要的,然后是第二次迁移中的“更新”部分,将“admin”列映射到“type_id”列。

有什么建议吗?

最佳答案

我发现使用 fk 比使用旧的 User.admin 加载 UserType 更“非传统”,我猜这经常发生。

如果你使用 fk's,你会得到丑陋的 mysql 错误,让用户感到困惑。否则,您使用 AR 验证和 Hook 来强制执行参照完整性,您会得到漂亮且集成良好的错误消息,这些消息不会破坏应用程序的用户体验流程。

不要担心将运行一次的迁移,并考虑您在代码之外放置的业务逻辑。

这都是意见/惯例的问题,但我希望您发现我的见解有所帮助。

关于ruby-on-rails - 将更新逻辑放入您的迁移中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2887257/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com