2

Article と Category という 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

さて、レールコンソールで:

Article.all.search('test article')

予想通り、エラーを返します

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

しかし、私がこれを行うとき

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

一連のレコードを返します!

これにより、クラスのチェックが促されます

 Article.all

Category.first.articles

どちらもArrayクラスを返します。

明らかに、Article のクラス メソッド 'search' は実行時に導入され、関連付け (Category) を介してアクセスされた場合はレコードの「正しい」戻りを促しますが、クラス自体 (Article) によってアクセスされた場合は別の動作をします。

それで、何が起こっているのですか?

4

2 に答える 2

2

これは.all、クエリを実行すると実際に実行されるため、返されるオブジェクトは基本的な配列になるためです。ただし、 を実行するCategory.firstと、Category オブジェクトが返され、articles実際にActiveRecord::Reflection::AssociationReflectionは Array が使用され、拡張されます。たとえば、次のようにしrails cます。

Category.first.articles.ancestors

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

2 番目のものは、この時点でオブジェクトが単純な配列であるため、エラーをスローします。ただし、最初のものは次のようなもので構成されています。

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] 

配列のように見えますが、他のクラスを継承していることがわかります。

于 2011-03-29T18:29:56.323 に答える
0
Article.all

これは、あなたが見たようにエラーを与えている配列を返します.クラスでクラス関数を実行しようとしていArticleますArray.

あなたが何を達成しようとしているのか正確にはわかりませんが、これはできると思います

Article.search("soem content")

ただし、それが結果を返すかどうかはわかりません。

于 2011-03-29T17:57:47.627 に答える