Объединить массивы условий в Rails
Я использую бета-версию Rails3, гем will_paginate и плагин geokit gem &.
Поскольку плагин geokit-rails, похоже, не поддерживает области Rails3 (включая проблему с символом:origin), мне нужно использовать синтаксис.find.
Вместо областей мне нужно объединить два набора критериев в формате массива:
У меня есть условие по умолчанию:
conditions = ["invoices.cancelled = ? AND invoices.paid = ?", false, false]
Мне может понадобиться добавить одно из следующих условий к условию по умолчанию, в зависимости от выбора пользовательского интерфейса:
#aged 0
lambda {["created_at IS NULL OR created_at < ?", Date.today + 30.days]}
#aged 30
lambda {["created_at >= ? AND created_at < ?", Date.today + 30.days, Date.today + 60.days]}
#aged > 90
lamdba {["created_at >= ?", Date.today + 90.days]}
Результирующий запрос напоминает:
@invoices = Invoice.find(
:all,
:conditions => conditions,
:origin => ll #current_user's lat/lng pair
).paginate(:per_page => @per_page, :page => params[:page])
Вопросы:
- Есть ли простой способ объединить эти два набора условий (если я правильно сформулировал это)
- Хотя это не усугубляет проблему, есть ли СУХОЙ способ создать эти стареющие ведра?
- Есть ли способ использовать области Rails3 с плагином geokit-rails, который будет работать?
Спасибо за ваше время.
2 ответа
Попробуй это:
ca = [["invoices.cancelled = ? AND invoices.paid = ?", false, false]]
ca << ["created_at IS NULL OR created_at < ?",
Date.today + 30.days] if aged == 0
ca << ["created_at >= ? AND created_at < ?",
Date.today + 30.days, Date.today + 60.days] if aged == 30
ca << ["created_at >= ?", Date.today + 90.days] if aged > 30
condition = [ca.map{|c| c[0] }.join(" AND "), *ca.map{|c| c[1..-1] }.flatten]
Изменить подход 2
Обезьяна залатать Array
учебный класс. Создайте файл с именем monkey_patch.rb
в config/initializers
каталог.
class Array
def where(*args)
sql = args[0]
unless (sql.is_a?(String) and sql.present?)
return self
end
self[0] = self[0].present? ? " #{self[0]} AND #{sql} " : sql
self.concat(args[1..-1])
end
end
Теперь вы можете сделать это:
cond = []
cond.where("id = ?", params[id]) if params[id].present?
cond.where("state IN (?)", states) unless states.empty?
User.all(:conditions => cond)
Я думаю, что лучше использовать анонимные области.
Проверьте это здесь: http://railscasts.com/episodes/112-anonymous-scopes