哪个rails查询/链更好?

时间:2015-11-16 21:01:07

标签: sql ruby-on-rails activerecord chaining

我有一个带有以下型号的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)

解决方案2:

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 个答案:

答案 0 :(得分:2)

您应该在User上定义一个关联,该关联将返回executor_idassigner_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;

然后你可以像在“解决方案2”中那样做,但是你可以Task.alltasks(current_user)代替不幸的current_user.assigned_and_executed_tasks(当然你可以给它一个更短的名字,但描述性的名字是比短的更好):

@tasks = current_user.assigned_and_executed_tasks
           .uncompleted
           .order("deadline DESC")
           .paginate(page: params[:page], per_page: 12)

答案 1 :(得分:0)

解决方案2将是从数据库中检索记录的更有效方法。在大多数Rails应用程序中,对数据库的调用是瓶颈的常见原因,在解决方案2中,您只需调用一次数据库来检索所有记录,但在解决方案1中,您可以对数据库进行两次调用以检索相同的信息。

就个人而言,我也认为这个解决方案更易读,易于测试和维护,因此解决方案2在很多方面都超越了速度!