ActiveRecord::Relation.concat 在 Rails 5 中失败

Mel*_*emi 6 ruby activerecord ruby-on-rails activerecord-relation

愚蠢的问题,但我不确定为什么这会在 Rails 4.2 中起作用,但在 Rails 5.2 中不起作用。

FamilyCharacteristic.where(family_id: @user.family_ids)
                    .concat(@user.characteristics)
Run Code Online (Sandbox Code Playgroud)

规范在 5.2 中失败:

Failure/Error:
       FamilyCharacteristic.where(family_id: @user.family_ids)
                           .concat(@user.characteristics)

     NoMethodError:
       undefined method `concat' for #<ActiveRecord::Relation []>
       Did you mean?  count
Run Code Online (Sandbox Code Playgroud)

concat 是从ActiveRecord::Relation5.2 中删除的还是FamilyCharacteristic.where(family_id: @user.family_ids)在 < 4.2 中是不同的对象?

谢谢你的帮助。

aha*_*lak 6

我做了一些挖掘,发现:

  • FamilyCharacteristic.where(family_id: @user.family_ids)班级没变,还是 ActiveRecord::Relation
  • Relation没有也仍然没有定义自己的concat方法,但是它被委托给Array#concat直到这个提交发生,所以在 Rails 4.2 SomeModel.where(id: ids).concat(some_records)(它返回一个Array)实际上是一样的SomeModel.where(id: ids).to_a.concat(some_models)
  • 之后改变之前提到的ActiveRecord::Delegation用Rails 5.2,唯一的方法委托给Array在此模块中指定的那些并且concat不在其中

总而言之 -concat从你的例子来看,它从未属于ActiveRecord但被委托给它Array#concat,这就是它起作用的原因。它不再在 Rails 5 中委托,所以它抛出NoMethodError.

  • 除了 `concat`,您可以使用 `+` 使其工作起来最相似 - `FamilyCharacteristic.where(family_id: @user.family_ids) + @user.characteristics`。还有像 `merge` 这样的方法 - 但它使用 sql `AND` 子句,`or` - 使用 `OR` 子句,所以这似乎是正确的解决方案,但它要求关系在结构上兼容,所以我认为它不会在这种情况下工作。 (2认同)