为什么/如何只能通过 Rails 3 中的关联来访问记录数组的类方法?

发布于 2024-10-28 05:15:24 字数 832 浏览 0 评论 0原文

考虑一个简单的示例,其中我们有 2 个模型:文章和类别。

class Article < ActiveRecord::Base
  belongs_to :category

  def self.search(title)
    where(:title => title)
  end
end

class Category < ActiveRecord::Base
  has_many :articles
end

现在,在 Rails 控制台上:

Article.all.search('test article')

正如预期的那样返回错误

NoMethodError: undefined method `search' for #<Array:0x9aa207c>

但是当我这样做时

Category.first.articles.search('test article')

会返回一组记录!

这会提示检查 Array 类的类

 Article.all

Category.first.articles

返回该类。

显然,Article 的类方法“search”是在运行时引入的,并在通过其关联(Category)访问时提示“正确”返回记录,但在由类本身(Article)访问时则表现不同。

那么,发生了什么事?

Consider a simple example, where we have 2 models, Article and Category.

class Article < ActiveRecord::Base
  belongs_to :category

  def self.search(title)
    where(:title => title)
  end
end

class Category < ActiveRecord::Base
  has_many :articles
end

Now, on the rails console :

Article.all.search('test article')

As expected returns an error

NoMethodError: undefined method `search' for #<Array:0x9aa207c>

But when I do this

Category.first.articles.search('test article')

returns a set of records!

This prompts a check on the classes of

 Article.all

and

Category.first.articles

both returning the Array class.

Obviously, Article's class method 'search' is being inducted in run time and prompting a 'correct' return of records when accessed through its association (Category) but behaving otherwise when accessed by the class itself (Article).

So, What's happening?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

红焚 2024-11-04 05:15:24

这是因为当您执行.all时,查询实际上被执行,因此返回的对象将是一个基本数组。然而,当你执行Category.first时,它会返回一个Category对象,那么articles实际上是在利用ActiveRecord::Reflection::AssociationReflection 并对数组进行扩展。例如,在rails c中尝试:

Category.first.articles.ancestors

vs

Category.first.articles.all.ancestors #throws an error

第二个抛出错误,因为此时对象只是一个简单的数组。然而,第一个是由类似这样的内容组成的:

Article(...), ActiveRecord::Base, ActiveRecord::Reflection, Object (and so on)

作为另一个例子,试试这个:

a = Category.first.articles; ObjectSpace.each_object(Class).select {|k| a < k }
#=> [Object, BasicObject, ActiveRecord::Base] 

您可以看到,虽然它看起来像一个数组,但它继承了其他类。

This is because when you perform .all the query is actually executed, so the object returned will be a basic array. However, when you perform Category.first, it will return a Category object, then articles is actually making use of ActiveRecord::Reflection::AssociationReflection and doing an extension of an Array. For example, in rails c try:

Category.first.articles.ancestors

vs

Category.first.articles.all.ancestors #throws an error

The second one throws an error, because at this point the object is just a simple Array. The first, however, is made up of something like this:

Article(...), ActiveRecord::Base, ActiveRecord::Reflection, Object (and so on)

As another example, try this:

a = Category.first.articles; ObjectSpace.each_object(Class).select {|k| a < k }
#=> [Object, BasicObject, ActiveRecord::Base] 

You can see that although it looks like an Array, it's inheriting those other classes.

无声情话 2024-11-04 05:15:24
Article.all

这会返回一个数组,该数组会给出您所看到的错误,您正在尝试在 Array 类上运行 Article 的类函数。

我不确定你到底想要完成什么,但你可以这样做,我想

Article.search("soem content")

但是,我不确定这是否会返回结果,因为它可能只会返回

Article.all

This returns an array that's giving you the error as you saw, you're trying to run a class function of Article on the Array class.

I'm not sure what exactly you're trying to accomplish but you could do this, I think

Article.search("soem content")

However, I'm not sure if that would return a result, as it might just return an

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文