Ruby scope/ActiveRecord查询无操作

Ruby scope/ActiveRecord查询无操作,ruby,activerecord,Ruby,Activerecord,我正在尝试在Rails中运行add-scope,它只在参数传入时才起作用-有没有一种简洁的方法来避免混乱的1=1默认参数 scope :tagged, -> (tags) { [tags].flatten.compact.empty? ? where('1 = 1') : where("#{self.table_name}.tags @> ARRAY[?]::varchar[]", [tags].flatten.compact)} 基本上,在将返回当前查询并允许继续链接的作用域中,

我正在尝试在Rails中运行add-scope,它只在参数传入时才起作用-有没有一种简洁的方法来避免混乱的
1=1
默认参数

scope :tagged, -> (tags) { [tags].flatten.compact.empty? ? where('1 = 1') : where("#{self.table_name}.tags @> ARRAY[?]::varchar[]", [tags].flatten.compact)}

基本上,在将返回当前查询并允许继续链接的作用域中,
where('1=1')
的等价物是什么?返回
self
不起作用-它返回对象,需要从头开始重新构造所有链

范围
all
解决了您的问题。将您庞大的在线文档拆分为更具可读性的内容,可以:

scope :tagged, -> (tags) do
  if [tags].flatten.compact.empty? 
    all
  else
    where(
      "#{self.table_name}.tags @> ARRAY[?]::varchar[]",
      [tags].flatten.compact
    )
  end
end
但是,这可以更进一步:如果rails作用域返回
nil
,那么它将隐式调用
all
!换句话说,我们可以简单地写下:

scope :tagged, -> (tags) do
  if [tags].flatten.compact.present? 
    where(
      "#{self.table_name}.tags @> ARRAY[?]::varchar[]",
      [tags].flatten.compact
    )
  end
end

如果可能的话,我还建议简化调用此作用域的代码:您对
.flatte.compact
的调用有点狡猾!理想情况下,您应该对在方法之间传递的数据结构更有信心。
[tags].flatte.compact
实际上非常有用-它允许您使用带有
nil
、单个
tag
和一组
[tags]
的范围。更多的是灵活性而不是不信任。[*tags]是我实现这一点的首选方法。完全按照您所说的做(除了
nil
之外,还允许
[]
),并且不允许更多。为什么要使用
nil
的范围?如果有什么区别的话,那就是代码中其他地方出了问题的迹象(您在这里隐藏了错误)。至于使用单个标记与数组,这很好:您可以定义如下方法:
scope:taged,->(*tags){where(“…”,tags)if tags.present?}
这实际上是关于nil的一个好观点。我看不出单个标记将如何工作-在这种情况下,
taged(tag)
taged([tag])
是一样的吗?