连接范围结果的最佳方法

时间:2017-12-06 17:18:32

标签: ruby-on-rails activerecord scope

我有两个范围。一个检查db列是否为空或空字符串,另一个检查相反的(非空,而不是空字符串)

scope :has_something, where('something IS NOT NULL AND something != ""')
scope :has_no_something, where('something IS NULL OR something = ""')

我想最终将两个结果连接起来。即结果后面跟着没有结果的结果

我的第一次尝试是这样的:

def self.with_something_data_first
  has_something + has_no_something
end

这导致:

  

NoMethodError:#

的未定义方法`order'

因为此方法与订单组合

Model.with_something_data_first.order(:created_at).reverse_order.limit(20)

如果我能在一个范围内执行此操作会很棒,它会返回所有带有数据的记录,然后是所有带有空字符串或空字符串的记录。显然你不能以零命令,但也许你知道一个棘手的方法来解决这个问题吗?

4 个答案:

答案 0 :(得分:0)

scope :with_something_data_first, -> { order('something IS NULL OR something == ""') }

如何?

当某些东西为空或空字符串时,

something IS NULL OR something == ""计算结果为1,并且由于默认顺序为ASC,所有这些条目将显示在something IS NULL OR something == ""的记录之后,结果为0

答案 1 :(得分:0)

问题在于,当您连接两个范围时,您将获得一个数组,而不再是一个活动记录,因此您无法使用订单。不知道它是否是最佳方法,但您可以按照您获得的顺序从ID中进行新的查询。那将是这样的:

def self.with_something_data_first
  YourModel.find((has_something + has_no_something).map{|o| o.id})
end

像这样,您可以对其应用订单方法,因为您将拥有活动记录关系,并且它尊重您之前建立的对象的顺序。希望这有帮助!

答案 2 :(得分:0)

我最终想出了一个更能满足我需求的解决方案。而不是在db中检查空字符串和空值。我在输入时只是将空字符串切换为空值,并使用这样的命令将空值放在结果集的末尾。

scope :with_post_comments_first, order('-comment DESC')

答案 3 :(得分:-1)

这非常简单直接。理想情况下,您应该能够在两种条件下都得到结果吗?

如果是,请执行以下操作,

var request = new QueryRequest();
request.TableName = "YourTable";   
request.KeyConditions = new Dictionary<string, Condition>()
{
    { 
        "YourId",  new Condition()
        { 
            ComparisonOperator = "EQ",
            AttributeValueList = new List<AttributeValue>()
            {
                new AttributeValue { S = YourId }
            }
        }
    }
};

client.QueryAsync(request,(result));