如何在生产中将示例数据填充到我的Rails应用程序中?

时间:2019-04-02 12:46:23

标签: ruby-on-rails

我有一个n00b问题。我正在使用Rails 5,并希望在应用程序中包含示例数据。用户创建新项目时,该项目应该已经包含用户可以删除或编辑的示例“任务”。

我知道我可以在我的开发环境中使用seeds.rb创建示例数据。在生产环境中为新用户实现此功能的最佳方法是什么?我应该使用seed.rb,迁移还是rake任务?

示例控制器:

  def create
    @project = Project.new(project_params)
    @project.user = current_user

    if @project.save
       // add sample content
       redirect_to @project 
    else
       render :new
    end
  end

在项目模型中:

 belongs_to :user
 has_many :tasks, dependent: :destroy

当新用户加入并创建新项目时,如何在用户创建的新项目上自动添加示例“任务”?

更新:

要创建任务,我需要描述和当前用户的ID(我正在使用Devise,因此可以使用current_user帮助器),例如:

@project.tasks.create!(description: "hello", user_id: current_user.id)

5 个答案:

答案 0 :(得分:3)

您可以构建一个完成此任务的简单ServiceObject。它使您可以保持控制器的外观紧凑,并且可以使用current_user Devise帮助程序来跟踪哪个用户正在创建项目

if @project.save 
  SetupBaseProject.new(project).call
  redirect_to @project
else 
  # handle errors
end

app/services/setup_base_project.rb

class SetupBaseProject 
  def initialize(project, user) 
    @project = project
  end

  def call
    # Create example tasks and any additional setup you want to add
    @project.tasks.create(description: 'Hello World', user: @project.user)
  end    
end 

答案 1 :(得分:2)

考虑您的问题有两种可能的情况。

  1. 用户创建的第一个项目需要默认包含示例任务
  2. 无论何时创建新项目,默认情况下都会创建示例任务。不论用户是新用户还是现有用户。

对于第一种情况, 我们需要通过向用户添加一个布尔字段来跟踪项目是否由新用户创建,例如:new_user,默认值为true。 创建项目后,我们可以使用活动记录回调来生成示例任务。

例如, 项目模型:

belongs_to :user
has_many :tasks, dependent: destroy
after_create :generate_tasks
def generate_tasks
   if self.user.new_user #This conditional block can be modified as needed
     (1..3).each do |n|
       self.tasks.create!(description: "Sample task #{n}", user_id: self.user.id)
     end
   end
end

对于第二种情况, 我们可以使用相同的项目模型文件,而只是删除条件语句,这将有助于在创建项目后创建示例任务。

如果需要任何说明,请注释掉。

答案 2 :(得分:1)

我过去已经做过很多次了。 根据我的经验,您最终必须让其他人能够管理这些默认设置(产品所有者,市场营销等)

我过去所做的是让测试用户拥有一个充当“默认”项目的项目。

只要有人想创建一个新项目,就克隆它。

我为此使用了https://github.com/amoeba-rb/amoeba。它提供了一种突破性的方法来覆盖我想要更改的属性,并且可以将克隆级联到您想要克隆的任何关联。

答案 3 :(得分:0)

说样本数据在模型Detail上,该模型填充有seeds.rb并属于“项目”。您可以复制该记录并将其分配给新项目(未经测试):

def create
    @project = Project.new(project_params)
    @project.user = current_user
    @project.details << Detail.find_by_name('sample').dup

    if @project.save 
       redirect_to @company 
    else
       render :new
    end
  end

此外,在多个模型上保存数据时,请考虑使用事务。

答案 4 :(得分:0)

完全公开,我在Rails 4中工作...

如果是我,我将使用FactoryBot来获取所需的虚拟数据。工厂非常适合测试,因此,如果将它们用于测试,为什么不借用它们呢? post展示了一个示例,其中有人想要在控制台中模拟虚拟数据,相同的想法也可以在这里应用。

一旦您模拟了工厂……也许用于诸如以下的任务:

require 'faker'
FactoryBot.define do
  factory :task do
    transient do
      parent_project { nil }
    end

    description { Faker::Hacker.say_something_smart }
    project_id { parent_project.id }
  end
end

也许在项目模型中创建一个方法,例如:

def create_dummy_data
  require 'factory_bot'
  require 'faker'
  include FactoryBot::Syntax::Methods

  # create_list will spit out 3 tasks associated with your project
  create_list(:task, 3, parent_project: self)
end

然后在您的示例中:调用save ...

if @project.save
   @project.create_dummy_data  
   redirect_to @company 
else

我想不出您不能走这条路的原因...在控制台中四处闲逛我没有任何问题,但我会将这个答案视为起点,而不是最终解决方案= P