2

我正在尝试使用此处第一个答案中建议的数组动态构建一组条件:One or more params in model find conditions with Ruby on Rails。但是,我似乎做错了什么,我不确定我所尝试的是否从根本上不合理,或者我只是在搞砸我的语法。

我在这里简化为一个条件以试图说明这个问题,因为我试图按照这些思路构建一个简单的概念证明,然后再对我正在处理的 5 种不同的条件样式进行分层。

这有效:

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

这会导致一个名为“scan”的私有方法错误:

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

感谢您的任何建议。我不确定是否将其作为我在顶部提到的相关问题/答案的后续项目。因为我有问题而不是答案。如果有更好的方法来发布与现有帖子相关的内容,请告诉我。

4

3 回答 3

5

尝试这个:

导轨 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
于 2010-03-24T22:02:39.010 回答
3

你要:

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

代替:

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

+=将两个数组加在一起(将其视为将两个数组合并为一个数组),同时<<将一个新元素推送到数组中。所以你得到:[["id not in (?)", excluded]]当使用<<, 并且:conditions想要一个数组,其中第一个元素是一个字符串(不是数组)。

于 2010-03-24T21:09:06.290 回答
2

试试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哈希而不是有序参数也是更可取的。随着项目的发展,可能会出现更多的情况,而您将忘记哪个是哪个。哈希的外观和行为更清晰,而且您可以轻松验证它以避免软件错误。

于 2010-07-23T19:25:45.840 回答