TLDR: Is there a way to scope acts_as_list
into another table as such
class SprintTodo < ApplicationRecord
belongs_to :sprint
belongs_to :todo
acts_as_list scope: [:sprint, :todo.status]
end
I have two tables with one joining table.
Todo(name, position, status, parent, children, ...)
SprintTodo(todo_id, sprint_id, position)
Sprint(name, start_date, end_date, ...)
Todo
has its own position based on its parents (tree) while SprintTodo
holds the position as in Kanban Board based on its status.
The problem I am facing right now is that I cannot reach into Todo
table to scope it that way. One solution (although a bad one) is to replicate Todo
status in SprintTodo
as well but that would be bad design.
Is there any other way I can scope it on status?
CodePudding user response:
It'll probably be simpler to add a status column to SprintTodo
instead. But there is a way:
class SprintTodo < ApplicationRecord
belongs_to :todo
belongs_to :sprint
acts_as_list scope: "sprint_todos.id IN (\#{todo_status_sql}) AND sprint_todos.sprint_id = \#{sprint_id}"
def todo_status_sql
SprintTodo.select(:id).joins(:todo).where(todo: { status: todo.status }).to_sql
end
end
Sprint.create!
Todo.create!([{ status: :one }, { status: :one }, { status: :two }, { status: :two }])
Sprint.first.todos << Todo.all
Sprint.create!
Sprint.second.todos << Todo.create(status: :one)
>> SprintTodo.all.as_json(only: [:position, :sprint_id], include: {todo: {only: [:status, :id]}})
=>
[{"position"=>1, "sprint_id"=>1, "todo"=>{"id"=>1, "status"=>"one"}},
{"position"=>2, "sprint_id"=>1, "todo"=>{"id"=>2, "status"=>"one"}},
{"position"=>1, "sprint_id"=>1, "todo"=>{"id"=>3, "status"=>"two"}},
{"position"=>2, "sprint_id"=>1, "todo"=>{"id"=>4, "status"=>"two"}},
{"position"=>1, "sprint_id"=>2, "todo"=>{"id"=>5, "status"=>"one"}}]
# ^ ^ ^
# positioned by sprint and todo.status