Reputation: 27
I'm working on a fitness tracking app where we encourage you to track a habit for 30 days.
Every user has_many projects, projects belong_to user, projects has_many tasks, and tasks belong_to projects.
What I'm looking to do is when a project is created, I want to populate 30 empty tasks which will be displayed in order of day, and allow the user to click on a day and update the task. (see image) enter image description here
I'm happy to post any of the code/views if you need reference. Thanks for the help!
Upvotes: 0
Views: 39
Reputation: 102443
class Project < ActiveRecord::Base
has_many :tasks
def create_tasks!(n = 30)
self.class.transaction do
1..n.each do |day|
self.tasks.create(day: day)
end
end
end
end
Wrapping a mass insert in a single transaction is vital for performance - otherwise each insert will be run in its own transaction.
You could use a after_create
model callback to call create_tasks!
- but this can be problematic since the callback will fire every time you create a project which can make tests slow.
class Project < ActiveRecord::Base
has_many :tasks
after_create :create_tasks!
def create_tasks!(n = 30)
self.class.transaction do
1..n.each do |day|
self.tasks.create(day: day)
end
end
end
end
Another way to this would be to call it in your controller:
class ProjectsController < ApplicationController
def create
@project = Project.new(project_params)
if @project.save
@project.create_tasks!
redirect_to @project
else
render :new
end
end
end
Which gives you better control over exactly where in the application it happens.
Upvotes: 1
Reputation: 1152
You can make use of Active Record's after_create
callback, which allows you to perform a task whenever a new record is created for a certain model:
class Project < ActiveRecord::Base
has_many :tasks
after_create :create_empty_tasks
private
def create_empty_tasks
# Create your 30 Task objects
30.times do |i|
Task.create(day: (i + 1), project: self) # Update to match your schema
end
end
end
You'll of course need to update that code to pass any user-specific data into the Task
, but hopefully the callback is a good starting point.
Upvotes: 1