オブジェクトの配列を属性値でフィルタリングするRails


95

だから私はデータベースにクエリを実行し、オブジェクトの完全な配列を持っています:

@attachments = Job.find(1).attachments

今私は、オブジェクトの配列を持っていることを私は別のDBクエリを実行する必要はありませんが、私はに基づいて、配列をフィルタリングしたいAttachmentオブジェクトのfile_type私がのリスト持つことができるようにattachments、ファイルの種類がどこにあるか'logo'との、その後別のリストattachmentsファイルタイプは'image'

このようなもの:

@logos  = @attachments.where("file_type = ?", 'logo')
@images = @attachments.where("file_type = ?", 'image')

しかし、dbクエリの代わりにメモリ内。


以下のために良いユースケースのように思えるpartition- ここでの例
SRack

回答:


172

試してください:

これは結構です:

@logos = @attachments.select { |attachment| attachment.file_type == 'logo' }
@images = @attachments.select { |attachment| attachment.file_type == 'image' }

ただし、パフォーマンスを向上させるために、@ attachmentsを2回繰り返す必要はありません。

@logos , @images = [], []
@attachments.each do |attachment|
  @logos << attachment if attachment.file_type == 'logo'
  @images << attachment if attachment.file_type == 'image'
end

2
@Vikのソリューションは非常に理想的であるため、バイナリの場合に追加します。'partition '関数を使用して、物事を甘くすることができます。 ruby-doc.org/core-1.9.3/Enumerable.html#method-i-partition
Vlad

@Vladに感謝します。これはすばらしいことですが、オブジェクトから2つだけを収集する必要がある場合にのみサポートされます。
Vik

1
はい、それが私が「バイナリ」と言った理由です:)。質問では、明らかにロゴまたは画像の選択があったので、完全を期すためにこれを追加しました。
Vlad

8

添付ファイルが

@attachments = Job.find(1).attachments

これは添付オブジェクトの配列になります

selectメソッドを使用して、file_typeに基づいてフィルタリングします。

@logos = @attachments.select { |attachment| attachment.file_type == 'logo' }
@images = @attachments.select { |attachment| attachment.file_type == 'image' }

これは、dbクエリをトリガーしません。


2

熱心なロードを試しましたか?

@attachments = Job.includes(:attachments).find(1).attachments

すみません、はっきりしていません。配列をループせずにオブジェクト属性の値でフィルタリングするにはどうすればよいですか?
joepour

私が正しく理解していれば、dbクエリの数は少なくて済みます。特に、実行などのクエリが@attachments = Job.first.attachments実行されたら、ループし、@attachmentsその間、dbクエリはもう必要ありません。これはあなたがやりたいことですか?
Siwei Shen申思维2012

dbクエリを実行し、オブジェクトの配列を受け取ります。次に、属性の値に基づいてオブジェクトをフィルタリングすることにより、その1つの配列から2つの別個のリストを作成します(元の投稿を参照)
-cheers


0

これについては少し違った方法で考えます。クエリを構造化して、必要なものだけを取得し、そこから分割します。

したがって、クエリを次のようにします。

#                                vv or Job.find(1) vv
attachments = Attachment.where(job_id: @job.id, file_type: ["logo", "image"])
# or 
Job.includes(:attachments).where(id: your_job_id, attachments: { file_type: ["logo", "image"] })

そして、データを分割します:

@logos, @images = attachments.partition { |attachment| attachment.file_type == "logo" }

これにより、目的のデータがきちんと効率的に取得されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.