【问题标题】:convert and optimize SQL Query to Active Record query in Rails 4在 Rails 4 中将 SQL 查询转换和优化为 Active Record 查询
【发布时间】:2016-11-15 11:41:32
【问题描述】:

如何在 Rails 的 Active Record 查询中重写这个 SQL 查询

sqlQuery = "SELECT real_estate_agent_assignment_statuses.assignment_status, 
COUNT(developer_referrals.id) AS rea_count FROM 
real_estate_agent_assignment_statuses LEFT OUTER JOIN developer_referrals ON 
developer_referrals.real_estate_agent_assignment_status_id = 
real_estate_agent_assignment_statuses.id AND developer_referrals.project_id =
 1 AND developer_referrals.developer_staff_id IN (266) WHERE 
real_estate_agent_assignment_statuses.assignment_status IN ('Pending 
Eligibility Check', 'Completed Eligibility Check') AND 
real_estate_agent_assignment_statuses.deleted_at IS NULL GROUP BY 
real_estate_agent_assignment_statuses.assignment_status, 
real_estate_agent_assignment_statuses.rank ORDER BY 
real_estate_agent_assignment_statuses.rank ASC"

【问题讨论】:

    标签: ruby-on-rails postgresql ruby-on-rails-4 activerecord arel


    【解决方案1】:

    我的 SQL 生锈了,但我认为这会让你开始。

    sql_query1 = RealEstateAgentAssignmentStatus.joins(:developer_referrals)
                                                .where(:assignment_status => ['Pending Eligibility Check', 'Completed Eligibility Check'])
                                                .group(:assignment_status)
                                                .order(:rank)
                                                .all
    

    http://apidock.com/rails/ActiveRecord/QueryMethods

    【讨论】:

      【解决方案2】:

      通过正确的scopes 和关系设置,您几乎可以做任何事情。

      第一步是定义关系和范围。我只是猜测你的关系是什么,但即使完全不同,下面的代码也应该大致显示它是如何工作的:

      class DeveloperReferral < ActiveRecord::Base
        belongs_to :project
        belongs_to :staff_member
      
        scope :with_project, ->(project) {
          # merging allows you to define conditions on the join
          joins(:project).merge( Project.where(id: project) )
        }
      
        scope :with_staff_member, ->(staff_member) {
          # merging allows you to define conditions on the join
          joins(:staff_member).merge( StaffMember.where(id: staff_member) )
        }
      end
      
      class RealEstateAgentAssignmentStatus < ActiveRecord::Base
        has_many :developer_referrals
      
        scope :with_status, ->(status) { where(status: status) }
        scope :not_deleted, -> { where(deleted_at: nil) }
      
        scope :with_project, ->(project) {
          # merging allows you to define conditions on the join
          joins(:developer_referrals).merge(
              DeveloperReferral.with_project(project)
            )
        }
      
        scope :with_staff_member, ->(staff_member) {
          # merging allows you to define conditions on the join
          joins(:developer_referrals).merge(
              DeveloperReferral.with_staff_member(staff_member)
            )
        }
      end
      

      然后您可以使用范围构建查询。

      project = Project.find(1)
      staff_members = project.staff_members
      
      statuses =
        RealEstateAgentAssignmentStatus
          .with_project(project)
          .with_staff_member(staff_members)
          .with_status([
              'Pending Eligibility Check',
              'Completed Eligibility Check',
            ])
          .not_deleted
          .order(
              # we use `arel_table` so that SQL uses the namespaced column name
              RealEstateAgentAssignmentStatus.arel_table(:rank),
            )
      

      然后你可以做你的组/计数:

      status_counts =
        statuses
          .group(
              # we use `arel_table` so that SQL uses the namespaced column name
              RealEstateAgentAssignmentStatus.arel_table(:assignment_status),
              RealEstateAgentAssignmentStatus.arel_table(:rank),
            )
          .count(:id)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-05
        • 2021-07-05
        • 2013-06-27
        相关资源
        最近更新 更多