哪个 rails query/chain 更好?
which rails query/chain is better?
我有一个 rails 应用程序,其中包含以下型号。对于给定用户,我同时拥有 assigned_tasks 和 executed_tasks。我想知道哪个选项更适合为给定用户获取所有任务(也执行和分配)。
task.rb
belongs_to :assigner, class_name: "User"
belongs_to :executor, class_name: "User"
user.rb
has_many :assigned_tasks, class_name: "Task", foreign_key: "assigner_id", dependent: :destroy
has_many :executed_tasks, class_name: "Task", foreign_key: "executor_id", dependent: :destroy
解决方案 1:
task.rb
scope :completed, -> { where.not(completed_at: nil) }
scope :uncompleted, -> { where(completed_at: nil) }
user.rb
def tasks_uncompleted
tasks_uncompleted = assigned_tasks.uncompleted.order("deadline DESC")
tasks_uncompleted += executed_tasks.uncompleted.order("deadline DESC")
tasks_uncompleted.sort_by { |h| h[:deadline] }.reverse!
end
tasks_controller:
@tasks = current_user.tasks_uncompleted.paginate(page: params[:page], per_page: 12)
方案二:
task.rb
scope :completed, -> { where.not(completed_at: nil) }
scope :uncompleted, -> { where(completed_at: nil) }
scope :alltasks, -> (u) { where('executor_id = ? OR assigner_id = ?', u.id, u.id) }
tasks_controller
@tasks = Task.alltasks(current_user).uncompleted.order("deadline DESC").paginate(page: params[:page], per_page: 12)
解决方案 2 是从数据库中检索记录的更有效方法。在大多数 Rails 应用程序中,对数据库的调用是瓶颈的常见原因,在解决方案 2 中,您调用数据库一次以检索所有记录,但在解决方案 1 中,您调用数据库两次以检索同样的信息。
就我个人而言,我也认为此解决方案更具可读性、易于测试和可维护性,因此解决方案 2 在许多方面都比速度更好!
您应该在用户上定义一个关联,该关联将 return 所有由 executor_id
或 assigner_id
关联的任务:
class User < ActiveRecord::Base
has_many :assigned_and_executed_tasks,
->(user) { where('executor_id = ? OR assigner_id = ?', user, user) },
class_name: 'Task',
source: :tasks
end
user = User.find(123)
user.assigned_and_executed_tasks
# => SELECT tasks.* FROM tasks WHERE executor_id = 123 OR assigner_id = 123;
然后你可以像在 "Solution 2," 中那样做,但你可以只做 current_user.assigned_and_executed_tasks
而不是不幸的 Task.alltasks(current_user)
(当然你可以给它一个更短的名字,但描述性名字比短的好):
@tasks = current_user.assigned_and_executed_tasks
.uncompleted
.order("deadline DESC")
.paginate(page: params[:page], per_page: 12)
我有一个 rails 应用程序,其中包含以下型号。对于给定用户,我同时拥有 assigned_tasks 和 executed_tasks。我想知道哪个选项更适合为给定用户获取所有任务(也执行和分配)。
task.rb
belongs_to :assigner, class_name: "User"
belongs_to :executor, class_name: "User"
user.rb
has_many :assigned_tasks, class_name: "Task", foreign_key: "assigner_id", dependent: :destroy
has_many :executed_tasks, class_name: "Task", foreign_key: "executor_id", dependent: :destroy
解决方案 1:
task.rb
scope :completed, -> { where.not(completed_at: nil) }
scope :uncompleted, -> { where(completed_at: nil) }
user.rb
def tasks_uncompleted
tasks_uncompleted = assigned_tasks.uncompleted.order("deadline DESC")
tasks_uncompleted += executed_tasks.uncompleted.order("deadline DESC")
tasks_uncompleted.sort_by { |h| h[:deadline] }.reverse!
end
tasks_controller:
@tasks = current_user.tasks_uncompleted.paginate(page: params[:page], per_page: 12)
方案二:
task.rb
scope :completed, -> { where.not(completed_at: nil) }
scope :uncompleted, -> { where(completed_at: nil) }
scope :alltasks, -> (u) { where('executor_id = ? OR assigner_id = ?', u.id, u.id) }
tasks_controller
@tasks = Task.alltasks(current_user).uncompleted.order("deadline DESC").paginate(page: params[:page], per_page: 12)
解决方案 2 是从数据库中检索记录的更有效方法。在大多数 Rails 应用程序中,对数据库的调用是瓶颈的常见原因,在解决方案 2 中,您调用数据库一次以检索所有记录,但在解决方案 1 中,您调用数据库两次以检索同样的信息。
就我个人而言,我也认为此解决方案更具可读性、易于测试和可维护性,因此解决方案 2 在许多方面都比速度更好!
您应该在用户上定义一个关联,该关联将 return 所有由 executor_id
或 assigner_id
关联的任务:
class User < ActiveRecord::Base
has_many :assigned_and_executed_tasks,
->(user) { where('executor_id = ? OR assigner_id = ?', user, user) },
class_name: 'Task',
source: :tasks
end
user = User.find(123)
user.assigned_and_executed_tasks
# => SELECT tasks.* FROM tasks WHERE executor_id = 123 OR assigner_id = 123;
然后你可以像在 "Solution 2," 中那样做,但你可以只做 current_user.assigned_and_executed_tasks
而不是不幸的 Task.alltasks(current_user)
(当然你可以给它一个更短的名字,但描述性名字比短的好):
@tasks = current_user.assigned_and_executed_tasks
.uncompleted
.order("deadline DESC")
.paginate(page: params[:page], per_page: 12)