【问题标题】:How to set up a Rake task for seeding如何设置用于播种的 Rake 任务
【发布时间】:2010-12-15 10:34:15
【问题描述】:

(这确实是一个关于 Rake & Rails & 依赖关系的新手问题。我试图弄清楚这一切是如何结合在一起的)

基本上,我想要一个 Rake 任务,它的行为类似于 seed.rb 但被单独调用。它为开发环境添加了测试数据,而我的seed.rb为所有环境提供了基础数据。

脚本 family_seed.rb 使用 FactoryGirl 生成一些记录。它看起来像这样:

require File.expand_path('../../config/environment', __FILE__)
require './spec/factories'

Family.delete_all
Member.delete_all
zinsser = Factory.create(:family, :last_name=>'Zinsser', :first_name=>'Carl', :sim_id => '500')
blackburn = Factory.create(:family, :last_name=>'Blackburn', :first_name=>'Greg', :sim_id => '501')

bundle exec "ruby db/family_seeds.rb" 运行良好,但我的问题是如何使用 Rake 进行设置。是否应该将整个事情放在 Rake 任务中?相反,我如何设置一个调用脚本的任务,同时确保 Rails 开发环境在运行时可用?我不仅要努力完成工作,还要以“正确”的方式去做。

【问题讨论】:

    标签: ruby-on-rails rake seed rake-task


    【解决方案1】:

    解决这个问题的一种方法是在 lib 中创建一个类或模块(这样可以更轻松地编写测试,并使代码更易于重用):

    require '../spec/factories'
    
    class FamilySeed
    
      def self.seed
        raise "Don't run this in production!" if Rails.env.production?
    
        Family.delete_all
        Member.delete_all
        zinsser = Factory.create(:family, :last_name=>'Zinsser', :first_name=>'Carl', :sim_id => '500')
        blackburn = Factory.create(:family, :last_name=>'Blackburn', :first_name=>'Greg', :sim_id => '501')
      end
    
    end
    

    如何创建rake任务:

    require 'family_seed'
    
    namespace :seed do
      task :families => :environment do
        FamilySeed.seed
      end
    end
    

    我会小心允许过于随意使用 Family.delete_all 和 Member.delete_all 之类的内容。以后你可以很容易地在生产数据库上调用一些你不想要的东西来打自己的脚。

    如何运行rake任务:

    在你的命令中运行它,如下所示:

    bundle exec rake seed:families
    

    【讨论】:

    • 这是一个很好的警告!有没有办法确保任务只在给定的环境中运行?诸如 FamilySeed 类之类的对象是否可以检查环境以查看它是测试版还是生产版?
    • 如果 rails env 是生产环境,我已经更新了代码以引发异常。
    • @idlefingers 感谢您的 rake 任务 - 我如何从命令行调用它?
    • @BKSpureon 你应该可以在命令行上运行它,比如bundle exec rake seed:families
    【解决方案2】:

    创建一个 rake 任务并需要 :environment

    task :delete_all => :environement do
      require Rails.root.join('spec/factories')
      Family.delete_all
      Member.delete_all
      zinsser = Factory.create(:family, :last_name=>'Zinsser', :first_name=>'Carl', :sim_id => '500')
      blackburn = Factory.create(:family, :last_name=>'Blackburn', :first_name=>'Greg', :sim_id => '501')
    end
    

    之后就可以运行这个任务rake delete_all

    【讨论】:

    • 这有助于展示如何在一项任务中完成所有工作。我缺少的关键是 ... => :environment 位。我喜欢将“delete_all”作为任务名称——这样不太可能意外运行它。
    猜你喜欢
    • 1970-01-01
    • 2011-05-11
    • 2014-04-26
    • 1970-01-01
    • 2016-09-18
    • 2010-10-09
    • 1970-01-01
    • 1970-01-01
    • 2013-05-12
    相关资源
    最近更新 更多