Ruby-on-rails 如何将新的种子数据添加到现有的 rails 数据库
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18569240/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to add new seed data to existing rails database
提问by toby
I am working on an application that is already deployed to some test and staging systems and various developers workstations. I need to add some additional reference data but i'm not sure how to add it.
我正在开发一个已经部署到一些测试和登台系统以及各种开发人员工作站的应用程序。我需要添加一些额外的参考数据,但我不确定如何添加。
Most of the advice says use seed.rb, however my understanding is that this is only run once, when the application is initially deployed. Since we don't want to rebuild the test and staging databases just so that we can add 1 row of reference data, is there another way to add the data?
大多数建议都说使用seed.rb,但是我的理解是这只会在最初部署应用程序时运行一次。既然我们不想重建测试和临时数据库只是为了我们可以添加1行参考数据,那么还有另一种添加数据的方法吗?
I'm thinking of using a db migration, is this the correct approach?
我正在考虑使用数据库迁移,这是正确的方法吗?
Thanks
谢谢
回答by nmott
Structure your seed.rb file to allow ongoing creation and updating of data. You are not limited to running a seed file only once and if you think it's only used for initial deployment you will miss out on the flexibility it can offer in setting reference data.
构建您的 seed.rb 文件以允许持续创建和更新数据。您不仅限于只运行一次种子文件,如果您认为它仅用于初始部署,您将错过它在设置参考数据方面提供的灵活性。
A seed file is just ruby so you can do things like:
种子文件只是 ruby,因此您可以执行以下操作:
user = User.find_or_initialize_by(email: '[email protected]')
user.name = 'Bob'
user.password = 'secret'
user.role = 'manager'
user.save!
This will create new data if it doesn't exist or update the data if it finds some.
如果它不存在,这将创建新数据,如果找到一些则更新数据。
If you structure your seed file correctly you can also create and update dependent objects.
如果您正确构建了种子文件,您还可以创建和更新相关对象。
I recommend using the bang save to ensure that exceptions are raised in the event that an object cannot be saved. This is the easiest method of debugging the seed.
我建议使用 bang save 来确保在无法保存对象的情况下引发异常。这是调试种子的最简单方法。
I use the seedbank gemto provide more structure to my seed data, including setting data per environment, dependent seeds and more.
我使用种子库 gem为我的种子数据提供更多结构,包括设置每个环境的数据、相关种子等。
I don't recommend using migrations for seed data. There is a lack of flexibility (how do you target seed data to just one environment for instance) and no real way to build up a reusable set of data that can be run at any time to refresh a particular environment. You would also have a set of migrations which have no reference to your schema and you would have to create new migrations every time you wanted to generate new or vary current data.
我不建议对种子数据使用迁移。缺乏灵活性(例如,您如何将种子数据定位到一个环境)并且没有真正的方法来构建可随时运行以刷新特定环境的可重用数据集。您还将拥有一组不引用您的架构的迁移,并且每次您想要生成新的或改变当前数据时都必须创建新的迁移。
回答by Miotsu
You can use a migration, but that's not the safest option you have.
Say, for example, you add a record to a table via a migration, then in the future you change that table's schema. When you'll install the app somewhere, you won't be able to run rake db:migrate.
您可以使用迁移,但这不是您拥有的最安全的选择。举例来说,您通过迁移向表中添加一条记录,然后在将来更改该表的架构。当您将应用程序安装在某处时,您将无法运行rake db:migrate.
Seeds are always advisable because rake db:seedcan be run on a completely migrated schema.
种子总是可取的,因为rake db:seed可以在完全迁移的模式上运行。
If it's just for a record, go for the rails console.
如果只是为了记录,请使用 rails 控制台。
回答by konyak
It's best to use an idempotent method like this in seed.rb or another task called by seed.rb:
最好在seed.rb 或seed.rb 调用的其他任务中使用像这样的幂等方法:
Contact.find_by_email("[email protected]") || Contact.create(email: "[email protected]", phone: "202-291-1970", created_by: "System")
# This saves you an update to the DB if the record already exists.
Or similar to @nmott's:
或类似于@nmott 的:
Contact.find_or_initialize_by_email("[email protected]").update_attributes(phone: "202-291-1970", created_by: "System")
# this performs an update regardless, but it may be useful if you want to reset your data.
or use assign_attributesinstead of update_attributesif you want to assign multiple attributes before saving.
或者如果要在保存前分配多个属性,请使用assign_attributes代替update_attributes。
回答by Steve Carey
I use the seed file to add instances to new or existing tables all the time. My solution is simple. I just comment out all the other seed data in the db/seeds.rb file so that only the new seed data is live code. Then run bin/rake db:seed.
我一直使用种子文件向新表或现有表添加实例。我的解决方案很简单。我只是注释掉 db/seeds.rb 文件中的所有其他种子数据,以便只有新的种子数据是实时代码。然后运行bin/rake db:seed。
回答by Jaga Jugue
I did something like this in seed.rb
我在seed.rb中做了类似的事情
users_list = [
{id: 1, name: "Diego", age: "25"},
{id: 2, name: "Elano", age: "27"}
]
while !users_list.empty? do
begin
User.create(users_list)
rescue
users_list = users_list.drop(1) #removing the first if the id already exist.
end
end
If a item in the list with the given id already exist it will return a exception, then we remove that item and try it again, until the users_list array is empty.
如果列表中具有给定 id 的项目已经存在,它将返回一个异常,然后我们删除该项目并重试,直到 users_list 数组为空。
This way you don't need to search each object before include it, but you will not be able tho update the values already inserted like in @nmott code.
这样你就不需要在包含它之前搜索每个对象,但你将无法像@nmott 代码那样更新已经插入的值。
回答by ehannes
Instead of altering seeds.db, which you probably want to use for seeding new databases, you can create a custom Rake task (RailsCast #66 Custom Rake Tasks).
seeds.db您可以创建一个自定义 Rake 任务(RailsCast #66 Custom Rake Tasks),而不是改变,您可能希望使用它来为新数据库做种。
You can create as many Rake tasks as you want. For instance, lets say you have two servers, one running version 1.0 of your app, the other one running 1.1, and you want to upgrade both to 1.2. Then you can create lib/tasks/1-0-to-1-2.rakeand lib/tasks`1-1-to-1-2.rakesince you may need different code depending on the version of your app.
您可以根据需要创建任意数量的 Rake 任务。例如,假设您有两台服务器,一台运行您的应用程序的 1.0 版,另一台运行 1.1 版,并且您想将它们都升级到 1.2 版。然后您可以创建lib/tasks/1-0-to-1-2.rake,lib/tasks`1-1-to-1-2.rake因为您可能需要不同的代码,具体取决于您的应用程序版本。

