Skip to content

Commit 9092403

Browse files
committed
Add task assignments and update documentation
1 parent 333b6b7 commit 9092403

File tree

13 files changed

+171
-25
lines changed

13 files changed

+171
-25
lines changed

.rubocop.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,7 @@ inherit_gem: { rubocop-rails-omakase: rubocop.yml }
88
# # Use `[a, [b, c]]` not `[ a, [ b, c ] ]`
99
# Layout/SpaceInsideArrayLiteralBrackets:
1010
# Enabled: false
11+
#
12+
AllCops:
13+
TargetRubyVersion: 3.1
14+

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
- Introduced complete! method in Todoro::Task to set completed_at timestamp and mark tasks as completed.
88
- Added Todoro::TaskStep model, allowing tasks to have multiple subtasks.
99
- Integrated Turbo to enable dynamic subtask creation and completion without full-page reloads.
10+
- Introduced `taskable_assignee`, allowing models to register as assignable entities.
11+
- Tasks now support dynamic polymorphic assignments to multiple assignees (e.g., `Employee`, `Role`).
12+
- Automatically generates `has_many` associations in `Todoro::Task` for each registered `taskable_assignee`.
1013

1114
### 0.1.5 - 2025-02-16
1215

README.md

Lines changed: 72 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,121 @@
11
# Todoro
22

3-
A lightweight Rails engine that lets any model manage task lists and tasks with a simple, flexible API.
3+
A lightweight Rails engine that enables any model to manage task lists and tasks with a simple, flexible API.
44

55
![Totoro](totoro.png)
66

77
## Installation
88

9-
Add to your Gemfile:
9+
Add `todoro` to your Gemfile:
1010

1111
```ruby
12-
gem "todoro"
12+
gem 'todoro'
1313
```
1414

15-
And then execute:
15+
Then execute:
1616

1717
```sh
1818
$ bundle install
1919
```
2020

21-
Or install it yourself as:
21+
Or install it manually:
2222

2323
```sh
2424
$ gem install todoro
2525
```
2626

2727
## Usage
2828

29+
### Setup
30+
2931
Generate the required migrations:
3032

3133
```sh
3234
$ rails generate todoro:install
3335
$ rails db:migrate
3436
```
3537

36-
Include `acts_as_taskable` in the model(s) that can have tasks:
38+
### Making Models Taskable
39+
40+
Include `acts_as_taskable` in any model that should manage tasks:
3741

3842
```ruby
3943
class Project < ApplicationRecord
4044
acts_as_taskable
4145
end
4246
```
4347

44-
Now, a `Project` can have task lists and tasks:
48+
This allows a `Project` to have task lists and tasks:
49+
50+
```ruby
51+
project = Project.create(name: 'Website Redesign')
52+
task_list = project.create_task_list('Development Tasks')
53+
task = project.add_task_to_list(task_list, 'Build homepage', 'Implement UI components')
54+
55+
puts project.tasks # Lists all tasks across its task lists
56+
```
57+
58+
### Assigning Tasks to Entities
59+
60+
To assign tasks to various entities (e.g., `User`, `Role`), ensure these models are assignable.
61+
62+
#### 1. Declare Assignable Models
63+
64+
In each model that should be assignable, simply call `taskable_assignee`:
4565

4666
```ruby
47-
project = Project.create(name: "Website Redesign")
48-
task_list = project.create_task_list("Development Tasks")
49-
task = project.add_task_to_list(task_list, "Build homepage", "Implement UI components")
67+
class User < ApplicationRecord
68+
taskable_assignee
69+
end
70+
71+
class Role < ApplicationRecord
72+
taskable_assignee
73+
end
74+
```
75+
76+
#### 2. Assign Tasks
77+
78+
With models configured, assign tasks as follows:
79+
80+
```ruby
81+
user = User.create(name: 'Jane Doe')
82+
role = Role.create(name: 'Developer')
83+
84+
# Assign task to assignable models
85+
task.assign_to(user)
86+
task.assign_to(role)
87+
88+
# Retrieve specific assignees
89+
task.employees # => [#<User id: 1, name: "Jane Doe">]
90+
task.roles # => [#<Role id: 1, name: "Developer">]
91+
```
92+
93+
### Managing Task Steps
94+
95+
Tasks can be broken down into multiple steps, allowing for a structured workflow.
96+
97+
```ruby
98+
# Add task steps
99+
task.task_steps.create(title: 'Design UI mockups')
100+
task.task_steps.create(title: 'Write backend API')
50101

51-
puts project.tasks # Lists all tasks in all its task lists
52102
```
53103

54104
## Automatic Route Generation
55105

56-
Todoro automatically generates routes for any model that includes `acts_as_taskable`. For example, if `Project` includes `acts_as_taskable`, the following routes are created:
106+
Todoro automatically generates routes for any model that includes `acts_as_taskable`. For example, if `Project` includes `acts_as_taskable`, this is part of the generated routes:
57107

58-
```sh
59-
GET /projects/:project_id/task_lists(.:format)
60-
POST /projects/:project_id/task_lists(.:format)
61-
GET /projects/:project_id/task_lists/:id(.:format)
62-
PATCH /projects/:project_id/task_lists/:id(.:format)
63-
DELETE /projects/:project_id/task_lists/:id(.:format)
64-
GET /projects/:project_id/task_lists/:task_list_id/tasks(.:format)
65-
POST /projects/:project_id/task_lists/:task_list_id/tasks(.:format)
108+
```
109+
/projects/:project_id/task_lists
110+
/projects/:project_id/task_lists/:id
111+
/projects/:project_id/task_lists/:id/tasks
112+
/projects/:project_id/task_lists/:id/tasks/:id
113+
/projects/:project_id/task_lists/:task_list_id/tasks/:id/complete
114+
/projects/:project_id/task_lists/:task_list_id/tasks/:task_id/step
115+
/projects/:project_id/task_lists/:task_list_id/tasks/:task_id/step/:id/complete
66116
```
67117

68-
These routes are automatically configured, so no additional setup is needed.
118+
These routes allow for managing task lists and tasks within the context of the `Project` model.
69119

70120
## Mounting the Engine
71121

@@ -74,7 +124,7 @@ To access Todoro's routes, mount the engine in your application's routes file:
74124
```ruby
75125
# config/routes.rb
76126
Rails.application.routes.draw do
77-
mount Todoro::Engine, at: "/"
127+
mount Todoro::Engine, at: '/'
78128
# Other routes...
79129
end
80130
```

app/models/todoro/task.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ class Task < ApplicationRecord
55
has_many :task_steps, class_name: "Todoro::TaskStep", dependent: :destroy
66

77
has_many :task_assignments, dependent: :destroy
8-
has_many :assignees, through: :task_assignments, source: :assignee
9-
108

119
validates :title, presence: true
1210
validates :status, presence: true, inclusion: { in: %w[pending completed] }

lib/todoro.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
require "todoro/version"
22
require "todoro/engine"
33
require "todoro/taskable"
4+
require "todoro/taskable_assignee"
45

56
module Todoro
67
mattr_accessor :assignable_models

lib/todoro/taskable_assignee.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,15 @@ module TaskableAssignee
1010
class_methods do
1111
def taskable_assignee
1212
Todoro.assignable_models << self.name unless Todoro.assignable_models.include?(self.name)
13+
14+
Todoro::Task.class_eval <<-RUBY, __FILE__, __LINE__ + 1
15+
has_many :#{self.name.underscore.pluralize}, through: :task_assignments, source: :assignee, source_type: "#{self.name}"
16+
RUBY
1317
end
1418
end
1519
end
1620
end
21+
22+
ActiveSupport.on_load(:active_record) do
23+
extend Todoro::TaskableAssignee::ClassMethods
24+
end
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class Employee < ApplicationRecord
2+
taskable_assignee
3+
end

spec/todoapp/app/models/user.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class User < ApplicationRecord
2+
taskable_assignee
3+
end
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# This migration comes from todoro (originally 20250217155125)
2+
class CreateTaskAssignments < ActiveRecord::Migration[7.2]
3+
def change
4+
create_table :todoro_task_assignments do |t|
5+
t.references :task, null: false, foreign_key: { to_table: :todoro_tasks }
6+
t.references :assignee, polymorphic: true, null: false
7+
8+
t.timestamps
9+
end
10+
end
11+
end
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class CreateUsers < ActiveRecord::Migration[7.2]
2+
def change
3+
create_table :users do |t|
4+
t.string :name
5+
6+
t.timestamps
7+
end
8+
end
9+
end

0 commit comments

Comments
 (0)