我在这个问题上一直在苦苦挣扎。我有一个相当复杂的查询,我拼凑在一起,但在我看来,它太冗长和丑陋。
我有一个高级门票搜索表单,其中包含8个不同的搜索字段,以及created_at和updated_at搜索选项,用户可以在其中选择日期,月份和/或年份来过滤其结果。
我正在我的ticket_controller中构建查询条件,如下所示。
conditions = String.new
arguments = []
unless params[:id].blank?
conditions << ' AND ' unless conditions.length == 0
conditions << 'tickets.id = ?'
arguments << params[:id]
end
unless params[:organization].blank?
conditions << ' AND ' unless conditions.length == 0
conditions << 'organizations.name ILIKE ?'
arguments << "%#{params[:organization]}%"
end
unless params[:keywords].blank?
conditions << ' AND ' unless conditions.length == 0
conditions << 'subject ILIKE ?'
arguments << "%#{params[:keywords]}%"
end
unless params[:status_id].blank?
conditions << ' AND ' unless conditions.length == 0
conditions << 'status_id = ?'
arguments << params[:status_id]
end
unless params[:resolution_status_id].blank?
conditions << ' AND ' unless conditions.length == 0
conditions << 'resolution_status_id = ?'
arguments << params[:resolution_status_id]
end
unless params[:priority_id].blank?
conditions << ' AND ' unless conditions.length == 0
conditions << 'priority_id = ?'
arguments << params[:priority_id]
end
unless params[:assigned_to_id].blank?
conditions << ' AND ' unless conditions.length == 0
conditions << 'assigned_to_id = ?'
arguments << params[:assigned_to_id]
end
@tickets = Ticket.joins(:organization).where(conditions, arguments).paginate(:page => params[:page], :per_page => 20).order("updated_at DESC")
对于有特殊连接的字段,我会感到困惑。例如,我有另一个表上的电子邮件列,并在tickets.rb中创建了一个单独的方法,如下所示。
def self.email(email)
joins('LEFT OUTER JOIN assignments ON assignments.person_id = tickets.owner_id').where('assignments.email_address ILIKE ?', email)
end
然后用这样的术语来调用它
params[:email].blank? ? nil : @tickets = @tickets.email("%#{params[:email]}%")
我还有一个联系人搜索字段,用于搜索我的人员表的名字和姓氏。我创建了一个看起来像这样的单独方法......
def self.contact(contact)
joins('LEFT OUTER JOIN people ON people.user_id = tickets.owner_id').where('people.last ILIKE ? OR people.first ILIKE ?', contact, contact)
end
然后像在params [:email]中那样用另一种方式调用它。 这对我而言似乎并不是最好的方式,但我是编程的新手,并且能够想出任何更优雅的东西。我有一些或这些三元运算符正在构建我的查询,虽然它工作得很好,但我不能帮助,但感觉我在这里做错了什么。 我希望这是足够的信息继续下去,如果不是我可以在需要时澄清。
答案 0 :(得分:0)
在我看来,你正在手动完成所有ActiveRecord
的工作。
我的每个案例都有一个范围:
例如:
#class Ticket < ActiveRecord::Base
scope :with_subject lambda { |keyword| where('subject ILIKE ?', keyword) }
scope :with_status_id { |s_id| where(status_id: s_id) }
将按如下方式使用:
@tickets = Ticket.scoped
@tickets = @tickets.with_subject(params[:keywords]) unless params[:keywords].blank?
@tickets = @tickets.with_status_id(params[:status_id]) if params[:status_id].present?
连接也可以链接在AR语法
中@tickets = @tickets.joins('LEFT OUTER JOIN people ON people.user_id = tickets.owner_id')
唯一的问题是使用OR
子句,IMO在SQL语法中更具可读性
where('people.last ILIKE ? OR people.first ILIKE ?', contact, contact)
希望它有所帮助。
PS:您可以在相关的Rails guide
上找到有关此主题的更多信息