Ruby on rails 在Ruby on Rails中使用固定装置植入数据是否危险

Ruby on rails 在Ruby on Rails中使用固定装置植入数据是否危险,ruby-on-rails,fixtures,random-seed,Ruby On Rails,Fixtures,Random Seed,我有需要保存在数据库中的初始数据(国家、地区、运营商等)。我有一个任务rake db:seed,它将为数据库种子 namespace :db do desc "Load seed fixtures (from db/fixtures) into the current environment's database." task :seed => :environment do require 'active_record/fixtures' Dir.glob(R

我有需要保存在数据库中的初始数据(国家、地区、运营商等)。我有一个任务rake db:seed,它将为数据库种子

namespace :db do
  desc "Load seed fixtures (from db/fixtures) into the current environment's database." 
  task :seed => :environment do
    require 'active_record/fixtures'

    Dir.glob(RAILS_ROOT + '/db/fixtures/yamls/*.yml').each do |file|
      Fixtures.create_fixtures('db/fixtures/yamls', File.basename(file, '.*'))
    end
  end
end

我有点担心,因为这个任务会清除我的数据库并加载初始数据。事实上,这甚至可以在生产中做不止一次,这吓坏了我。这是正常的吗?我需要谨慎吗?或者人们通常会以某种方式保护这样的任务吗?

Rails 3将使用seed.rb文件为您解决这个问题


在为数据库设定种子后,从生产服务器上删除任务怎么样?

用fixture设定数据种子是一个非常糟糕的主意

装置未经验证,而且由于大多数Rails开发人员不使用数据库约束,这意味着您可以很容易地将无效或不完整的数据插入到生产数据库中

namespace :db do
  desc "Load seed fixtures (from db/fixtures) into the current environment's database." 
  task :seed => :environment do
    require 'active_record/fixtures'

    Dir.glob(RAILS_ROOT + '/db/fixtures/yamls/*.yml').each do |file|
      Fixtures.create_fixtures('db/fixtures/yamls', File.basename(file, '.*'))
    end
  end
end
fixture还默认设置了奇怪的主键ID,这不一定是个问题,但使用起来很烦人

有很多解决方案。我个人最喜欢的是运行Ruby脚本的rake任务,该脚本只使用ActiveRecord插入记录。这就是Rails 3将如何处理
db:seed
,但您可以自己轻松编写

我用添加到ActiveRecord::Base的名为
create\u或\u update
的方法来补充这一点。使用这个,我可以多次运行seed脚本,更新旧记录,而不是抛出异常


不久前我写了一篇关于这些技术的文章。

对于你问题的第一部分,是的,我只是为在生产中运行这样的任务做了一些预防措施。我在引导/播种任务中设置了如下保护:

task :exit_or_continue_in_production? do
  if Rails.env.production?
    puts "!!!WARNING!!! This task will DESTROY " +
         "your production database and RESET all " +
         "application settings"
    puts "Continue? y/n"
    continue = STDIN.gets.chomp
    unless continue == 'y'
      puts "Exiting..."
      exit! 
    end
  end
end
我已经创建了一些上下文

对于问题的第二部分——通常您确实需要两件事:a)非常轻松地为数据库设定种子并为开发设置应用程序,以及b)在生产服务器上引导应用程序(例如:插入管理员用户、创建应用程序依赖的文件夹等)

我会使用fixture在开发中播种——团队中的每个人都会在应用程序中看到相同的数据,并且应用程序中的内容与测试中的内容是一致的。(通常我将
rake-app:bootstrap
rake-app:seed
rake-gems:install
等包装到
rake-app:install
中,这样每个人都可以通过克隆repo并运行这一个任务来处理应用。)


然而,我从不在生产服务器上使用固定装置进行种子设定/引导。Rails的db/seed.rb非常适合这个任务,但是您当然可以像其他人指出的那样,在自己的rake应用程序:seed任务中使用相同的逻辑

我有一个有趣的想法

如果您创建了\db\seeds\并添加了迁移样式文件,该怎么办

文件:200907301234_add_us_states.rb

class AddUsStates < ActiveRecord::Seeds

  def up
    add_to(:states, [
      {:name => 'Wisconsin', :abbreviation => 'WI', :flower => 'someflower'},
      {:name => 'Louisiana', :abbreviation => 'LA', :flower => 'cypress tree'}
      ]
    end
  end

  def down
    remove_from(:states).based_on(:name).with_values('Wisconsin', 'Louisiana', ...)
  end
end
这将允许您按顺序运行迁移和种子,使它们能够更和平地共存


想法?

我们已经建立了一系列用于播种数据的最佳实践。我们在很大程度上依赖于种子植入,并且我们有一些独特的需求,因为我们需要为多租户系统进行种子植入。以下是我们使用过的一些最佳实践:

  • fixture不是最好的解决方案,但是您仍然应该将种子数据存储在Ruby之外的其他东西中。用于存储种子数据的Ruby代码往往会重复,将数据存储在可解析文件中意味着您可以编写通用代码以一致的方式处理种子
  • 如果您打算潜在地更新种子,请使用名为
    code
    的标记列将种子文件与实际数据相匹配。永远不要依赖环境之间的一致性ID
  • 考虑如何处理现有种子数据的更新。用户是否有可能修改此数据?如果是这样,您是否应该维护用户的信息,而不是用种子数据覆盖它

  • 如果您对我们进行种子设定的某些方式感兴趣,我们已经将它们打包到一个名为的gem中。

    这将仅限于在数据库为空时加载吗?如果不是,为什么我还不能在销毁实时数据时意外地进行两次播种?很高兴这终于成为一个惯例!您将使用Ruby代码填充它,就像在迁移中写入种子数据一样。我的猜测是,它只会执行您放入seed.rb文件中的任何代码,因此它不会擦除数据库,而是添加到数据库中(或更新,取决于您的代码)。希望它有一个“忽略重复条目”选项,以便我可以在“附加”模式下进行两次种子设定,而不会有重复的数据……而且由于我处于“附加”模式,不必担心清除数据库是的,这是一个很好的调用,但我必须将其排除在repo之外,或者每次部署时文件都会返回…或者我可以让capistrano在部署后删除文件…我认为这样更好。我当然喜欢通过active record执行此操作,但我认为您不能这样设置主键。我必须试一试你文章中的方法。如果你正在播种没有关联模型的数据呢?如果它没有模型,这是否意味着你没有将数据存储在数据库中?在这种情况下,我会使用常量。你可以在初始值设定项中设置。我不能同意你的论点。我还是喜欢固定装置。而且比你的方法快得多!