我有一个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)
答案 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)
考虑您的问题有两种可能的情况。
对于第一种情况, 我们需要通过向用户添加一个布尔字段来跟踪项目是否由新用户创建,例如: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