web-dev-qa-db-ja.com

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

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

@attachments = Job.find(1).attachments

オブジェクトの配列ができたので、別のdbクエリを実行したくありませんが、Attachmentオブジェクトのfile_typeに基づいて配列をフィルター処理して、ファイルタイプがattachmentsのリストを持つ'logo'であり、ファイルタイプが'image'であるattachmentsの別のリスト

このようなもの:

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

ただし、dbクエリではなくメモリ内。

88
joepour

試してください:

これは結構です:

@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
163
Vik

添付ファイルが

@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クエリをトリガーしません。

8

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

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

私はこれについて少し違ったやり方で行きます。必要なものだけを取得してそこから分割するようにクエリを構成します。

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

#                                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" }

それはあなたがきちんと効率的な方法であなたが追いかけているデータを取得します。

0
SRack

Whereを使用してフィルタリングできます

Job.includes(:attachments).where(file_type: ["logo", "image"])
0