Home > Mobile >  Is there a way to scope acts_as_list based on column in another table?
Is there a way to scope acts_as_list based on column in another table?

Time:01-30

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.

  1. Todo(name, position, status, parent, children, ...)
  2. SprintTodo(todo_id, sprint_id, position)
  3. 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  

https://www.rubydoc.info/gems/acts_as_list/0.8.2/ActiveRecord/Acts/List/ClassMethods#acts_as_list-instance_method

  • Related