Planning stage - database structure questions

Subscribe to Planning stage - database structure questions 4 posts, 2 voices

 
Avatar bohara 10 posts

Hi, I am in the planning stage of an application where users can define a set of tasks by week, and can share these with other users. Once their plan is active they can edit each task and define what was actually completed.

I am imagining a table for “plans” and table “actuals” or something like that. So when a user selects an existing plan or creates a new plan – it could then be copied(selected and inserted) to the actuals table. Each user would also have unique starting and end dates based on their start date.

The plan would be a template that could be shared among users. And actuals would be a unique copy including what a user actually did.

I have two questions

1st – Does that make any sense? Is their a better way to accomplish this through a database relationship? 2nd – How would I copy all these records from on table to the other?

I’d love to hear your thoughts. Thanks

 
Avatar Jeff Cohen 89 posts

I think the “template plan” will need more than one table, actually.

It sounds like you’d need a template_plans table, where each row points to many rows in a template_tasks table. The template_tasks table is where the “default values” for the initial tasks can live (name, estimated duration, etc.).

Then you’d need two tables for the “actuals”: plans and tasks.

But since those tables are practically identical, it feels redundant. What about something like this?

Table: plans Columns: id, template (template is a boolean column)

Table: tasks Columns: id, plan_id, name, template (again, a boolean column)

In other words, a Plan has many Tasks. Both plans and tasks can be marked as “templates” or not (actuals). That way you can also quickly turn an actual into a new template by copying it and turning on the template flag.

If you’re using Rails 2.1, you can use named scopes to quickly query for template plans and their tasks – just let me know if you need an example for that.

Not sure if this helps…?

 
Avatar bohara 10 posts

Jeff, I think that is a good solution. less DB cruft. I am familiar with named scopes, although I have not used them before.

What do you think the best way is to turn a template into an actual, as many users will likely be using the same template?

I am thinking

  1. select the plan template and re-insert with a start_date and user_id
  2. select all associated plan template tasks and re-insert with new plan_id

My brain is having a hard time visualizing this part.

Thanks for you help.

 
Avatar Jeff Cohen 89 posts

Yeah, I think you have to do a brute-force copy of the plan and all of its tasks, something like:

actual_plan = Plan.create(plan.attributes)

# now copy all the tasks
plan.tasks.each do |task|
  actual_plan.tasks.create(task.attributes)
end

That’s off the top of my head, syntax might be off a bit. Probably best to wrap this inside of a method on Plan:

def create_actual_plan
   actual = Plan.new(self.attributes)
   actual.template = false
   actual.save

   actual.tasks.each { |task| self.tasks.create(task.attributes) }
   actual  # return the new plan
end

So now your controller just do this:

new_plan = plan.create_actual_plan
redirect_to new_plan   # assuming Rails 2.0.2 and higher

Again I’m just making this up off the top of my head, but I think it’s in the ballpark…?