如何在Ruby中使用多个#select块?

时间:2016-03-10 09:04:53

标签: ruby-on-rails ruby

我们说我有一个记录列表,如:

transactions = Transaction.all

我有以下实例方法@currency, @geo, @industry。我想选择具有以下标准的记录:

  • 选择所有字段currency等于@currency的交易,除非@currency为零,在这种情况下,我们会忽略条件(货币将意味着所有当货币为零时

  • 选择字段geo等于@geo的所有交易,除非@geo为零。

  • 选择字段industry等于@industry的所有交易,除非@industry为零。

我尝试了多个#select但没有运气如下:

transactions.select{ |i| (i.currency == @currency) unless @currency.nil? }.
        .select{ |i| (i.geo == @geo) unless @geo.nil? }.
        .select{ |i| (i.industry == @industry) unless @industry.nil? }

3 个答案:

答案 0 :(得分:2)

如果unless @currency.nil?nil,则@currency将返回nil(这是假的),这与您的预期相反。< / p>

您应该使用||代替:

transactions.select{ |i| (i.currency == @currency) || @currency.nil? }.
        select{ |i| (i.geo == @geo) || @geo.nil? }.
        select{ |i| (i.industry == @industry) || @industry.nil? }

在这种情况下,如果@currencynil,则第一个条件将返回true,并且所有元素都会将select框传递给下一个...

另一种选择是仅运行select 参数不是nil。在这种情况下,您希望将该行分成不同的块:

transactions.select!{ |i| (i.currency == @currency) } unless @currency.nil?
transactions.select!{ |i| (i.geo == @geo) } unless @geo.nil?
transactions.select!{ |i| (i.industry == @industry) } unless @industry.nil?

答案 1 :(得分:1)

尽可能使用AR / SQL代替Ruby处理:

transactions.where(currency: @currency, geo: @geo, industry: @industry)

答案 2 :(得分:1)

transactions.select do |t|
  (@currency.nil? || t.currency == @currency) &&
  (@geo.nil? || t.geo == @geo)  &&
  (@industry.nil? || t.industry == @industry)
end

这应该可以胜任。

或者,如果你涉及动态:

[:currency, :geo, :industry].all? do |field|
   (ivar = instance_variable_get("@#{field}")).nil? || t.send(field) == ivar
end