Создание активных условий записи в массиве - частный метод «сканирование» называется ошибкой

StackOverflow https://stackoverflow.com/questions/2511242

Вопрос

Я пытаюсь построить набор условий динамически, используя массив, как предложено в первом ответе здесь: Один или несколько параметров в модели найдите условия с Ruby On Rails. Анкет Однако я, кажется, делаю что -то неправильно, и я не уверен, что то, что я пытаюсь, принципиально необоснованно или я просто понял свой синтаксис.

Я упрощаюсь до одного условия здесь, чтобы попытаться проиллюстрировать эту проблему, поскольку я пытался создать простое доказательство концепции по этим направлениям, прежде чем уловить на 5 различных стилях состояния, с которыми я сталкиваюсь.

Это работает:

excluded.push 12
excluded.push 30
@allsites = Site.all(:conditions => ["id not in (?)", excluded])

Это приводит к частному методу «сканирование», называемое ошибкой:

conditionsSet = []
excluded.push 12
excluded.push 30
conditionsSet << ["id not in (?)", excluded]
@allsites = Site.all(:conditions => conditionsSet)

Спасибо за совет. Я не был уверен, что правильная вещь заключалась в том, чтобы поместить это в качестве последующего элемента к соответствующему вопросу/ответам, которые я отметил наверху. Так как у меня есть проблема, а не ответ. Если есть лучший способ опубликовать это, связанное с существующим постом, пожалуйста, дайте мне знать.

Это было полезно?

Решение

Попробуй это:

Рельсы 2.3

class Site < ActiveRecord::Base

  def self.build_conditions(ids, name=nil, state=nil)
     cond = []
     cond << send(:sanitize_sql_array, ["id NOT IN (?)", ids]) unless ids.empty?
     cond << send(:sanitize_sql_array, ["name = ? ", name]) unless name
     cond << send(:sanitize_sql_array, ["state = ? ", state]) unless state
     cond.join(" and ")
  end    
end

Теперь где -то в вашем контроллере:

Site.all(:conditions => Site.build_conditions([1,2])) 
Site.all(:conditions => Site.build_conditions(nil, "ABC"))

Рельсы 3

class Site < ActiveRecord::Base          
  def self.exclude_ids_by_name_and_state(ids, name=nil, state=nil)
    result = scoped
    result = result.where("id NOT IN (?)", ids) if ids.present?
    result = result.where(:name => name) if name.present?
    result = result.where(:state => state) if state.present?
    result
  end    
end

Теперь где -то в вашем контроллере:

Site.exclude_ids_by_name_and_state([1,2])).all 
Site.exclude_ids_by_name_and_state(nil, "ABC").all

Другие советы

Ты хочешь:

conditionsSet += ["id not in (?)", excluded]

вместо:

conditionsSet << ["id not in (?)", excluded]

+= добавляет два массива вместе (подумайте об этом как об объединении в один массив), пока << Толкает новый элемент на массив. Итак, вы получаете: [["id not in (?)", excluded]] когда используешь <<, а также :conditions хочет массив, где этот первый элемент - строка (не массив).

Пытаться SmartTuple, он разработан специально для таких случаев.

def self.build_conditions(options = {})
  [
    SmartTuple.new(" AND "),
    (["id NOT IN (?)", ids] if options[:ids].present?),
    ({:name => options[:name]} if options[:name].present?),
    ({:state => options[:state]} if options[:state].present?),
  ].sum.compile
end

...

Site.all(:conditions => Site.build_conditions(:ids => {1,2]))
Site.all(:conditions => Site.build_conditions(:name => "abc", :state => "disabled")

Для меня это также предпочтительно использовать options хэш вместо упорядоченных аргументов. По мере того, как ваш проект растет, может появиться больше условий, и вы потеряете то, что происходит. Хэш выглядит и ведет себя более яснее, плюс вы можете легко проверить его, чтобы избежать ошибок программного обеспечения.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top