ruby on rails-ActiveRecord关系和对象模型



嗨,我最近在尝试执行以下操作时遇到了这个问题:

posts = User.first.posts
posts.find {|p| "p.id" == 123} => ActiveRecord::RecordNotFound: Couldn't find Post without an ID

这是在尝试调用ActiveRecord查找。它期待:

posts.find(123)

但是我不想再查询数据库了。所以我需要做:

posts.to_a.find {|p| "p.id" == 123}

根据post.class,我以为我在处理一个数组。为什么我必须调用它上的to_a?

posts.class => Array
posts.superclass => ActiveRecord::Base

如果它(大概(是Array的实例,为什么我可以在posts上调用超类?为什么它会返回ActiveRecord::Base?

还有:

posts.ancestors.include? ActiveRecord::Base => false

如果ActiveRecord::Base是posts数组的超类,为什么会出现错误?

再来一次。如果我这样做:

posts.instance_methods(false)

它返回关系类的实例方法,即Post。这似乎很奇怪,因为帖子是一个数组。类似地,如果我创建一个"常规"数组:

a = [1, 2]
a.instance_methods(false) => NoMethodError: undefined method `instance_methods' for [1, 2]:Array

因此,通过ActiveRecord关系查询返回的数组有点像数组,但不是。。。它似乎继承了ActiveRecord,但它并没有。。。或者什么的。就在我认为我已经完全掌握了Ruby对象模型的时候:(也许深入了解一下ActiveRecord会有所帮助。我不确定,我想这就是我问的原因。

这只是一件令人好奇的事情。感谢任何帮助/指导

您想要:

posts.detect {|p| p.id == 123}

finddetect的别名,但它被从posts返回的ActiveRecord集合代理上的find方法遮蔽。

find方法仅在ActiveRecord::基类上可用。它是一个类方法,而不是实例方法。

是的,这并不完全是一个数组,但它的行为确实像Enumerable。

在这种情况下,您可以使用select

posts.select{|p| p.id == 123}.first

我在末尾添加了.first,因为select将返回另一个数组,无论它只包含一个元素。

希望这能有所帮助。

看起来ActiveRecord::Base覆盖了您想要从Enumerable中获得的#find方法。这就是为什么您需要将它转换为一个没有覆盖find方法的数组。

posts.ancestors.include? ActiveRecord::Base => false

为false,因为posts是Post对象的集合,而不是ActiveRecord::Base的后代。posts集合中的任何单个项目都将是ActiveRecord::Base 的后代

相关内容

  • 没有找到相关文章

最新更新