61

正しい機会に使用していることを確認し、微妙な点を知りたいです。それらは同じように機能しているように見えます。つまり、コンソールを介してそれらを使用し、グーグル検索を行ったときにオンラインで多くの情報がない場合、オブジェクトフィールドが定義されているかどうかを確認します。ありがとう!

4

6 に答える 6

88

明確にするために:「純粋な」ルビーでも、どちらpresent?exists?Rails-landからのものではありません。

現在?

present?のActiveSupport拡張機能Objectです。これは通常、オブジェクトの一般的な「偽り」のテストとして使用されます。ドキュメントから:

オブジェクトはpresent、そうでない場合blank?です。オブジェクトはblank、それがfalse、空、または空白文字列の場合です。

したがって、たとえば:

[ "", " ", false, nil, [], {} ].any?(&:present?)
# => false

存在しますか?

exists?ActiveResourceからです。そのドキュメントから:

リソースの存在をアサートし、リソースが見つかった場合はtrueを返します。

Note.create(:title => 'Hello, world.', :body => 'Nothing more for now...')
Note.exists?(1) # => true
于 2012-11-01T22:58:08.057 に答える
27

2つのメソッドの大きな違いは、呼び出すpresent?と、見つかったレコードごとにActiveRecordが初期化される(!)が、そうでexists?はないことです。

これを示すために、Userにafter_initializeを追加しました。次のように出力されます。'オブジェクトを初期化しました!'

User.where(name:'mike')。present?

User Load (8.1ms) SELECT "users".* FROM "users" WHERE "users"."name" = $1 ORDER BY users.id ASC  [["name", 'mike']]
You have initialized an object!
You have initialized an object!

User.exists?(名前:'マイク')

User Exists (2.4ms)  SELECT 1 AS one FROM "users" WHERE "users"."name" = $1 ORDER BY users.id ASC LIMIT 1  [["name", 'mike']]
于 2015-05-12T13:53:01.787 に答える
20

パフォーマンスには大きな違いがあり、チェックしている関係によっては、.present?最大10倍遅くなる可能性があります。.exists?

この記事.present?では、 vs .any?vsのベンチマーク.exists?を行い、なぜそれらが遅いものから速いものへとこの順序で進むのかを説明します。

一言で言えば、.present?例では900ms)は返されたすべてのレコードをロードし、.any?例では100ms)はSQLCountを使用してそれが0より大きいかどうかを確認し、.exists?例では1ms)はSQLLIMIT1を使用する賢い子供ですすべてをロードせずに、すべてをカウントせずに、少なくとも1つのレコードがあるかどうかを確認します。

于 2017-05-04T05:20:55.253 に答える
9

SELECT COUNT(*)レコードをスキャンしてカウントを取得します。

SELECT 1最初の試合の後に停止するので、彼らの実行時間は非常に異なります。

于 2016-09-29T15:50:39.240 に答える
2

2つによって生成されるSQLも異なります。

present?

Thing.where(name: "Bob").present?
# => SELECT COUNT(*) FROM things WHERE things.name = "Bob";

exists?

Thing.exists?(name: "Bob")
# => SELECT 1 AS one from things WHERE name ="Bob" limit 1;

どちらも同じ速度で動作しているように見えますが、状況によって異なる場合があります。

于 2014-10-24T04:30:46.283 に答える
-3

以下を使用して、データベースクエリを回避できますpresent?

all_endorsements_11 = ArtworkEndorsement.where(user_id: 11)
ArtworkEndorsement Load (0.3ms)  SELECT "artwork_endorsements".* FROM "artwork_endorsements" WHERE "artwork_endorsements"."user_id" = $1  [["user_id", 11]]
all_endorsements_11.present?
=> true 
all_endorsements_11.exists?
ArtworkEndorsement Exists (0.4ms)  SELECT  1 AS one FROM "artwork_endorsements" WHERE "artwork_endorsements"."user_id" = $1 LIMIT 1  [["user_id", 11]]
=> true 
于 2017-02-15T19:49:42.293 に答える