ActiveRecord的关系和对象模型
嗨努力做到以下几点,当我最近就遇到了这个: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}
我虽然我正在处理一个数组,根据posts.class。为什么我必须打电话给to_a?
posts.class => Array
posts.superclass => ActiveRecord::Base
为什么我可以调用父类的职位,如果是(大概)阵列的一个实例,为什么它返回的ActiveRecord :: Base的?
另外:
posts.ancestors.include? ActiveRecord::Base => false
为什么是假的,如果的ActiveRecord :: Base的是职位阵列的超?
还有一个。如果我这样做:
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中引入一些底层的看法会有所帮助。我不确定,这就是为什么我问我猜。
这只是一件好奇的事情。任何帮助/指导表示赞赏
查找方法只适用于ActiveRecord :: Base类。它是一个类方法,而不是一个实例方法。
是的,这不完全是一个数组,但它的行为像一个Enumerable。
在这种情况下,你可以在最后使用select
posts.select{|p| p.id == 123}.first
我加了。首先,因为选择将返回另一个数组,只有一个元素吧。
希望这会有所帮助。
正确的方法是在这里使用'detect'而不是'select',因为'detect'会返回遇到的第一个元素并停止查找。只是一个有用的供参考。 – 2011-04-11 22:49:29
你想:
posts.detect {|p| p.id == 123}
find
是detect
的别名,但它是由你得到posts
回来ActiveRecord的收集代理find
方法阴影。
posts.ancestors.include? ActiveRecord::Base => false
是错误的,因为posts是Post对象的集合,而不是ActiveRecord::Base
的后裔。文章集合中的任何单个项目都将是ActiveRecord::Base
的后裔
为什么要在块中将字符串与int进行比较?你为什么要做'posts.find {| p | “p.id”== 123}'而不是'p.id'? – Geo 2011-04-11 22:35:52
是的,这是一个错字。谢谢指出 – jgoggles 2011-04-11 22:54:59