[ruby-on-rails] 속성 값으로 객체 배열을 필터링하는 Rails

그래서 db에 대한 쿼리를 수행하고 완전한 객체 배열을 가지고 있습니다.

@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 쿼리 대신 메모리에 있습니다.



답변

시도해보십시오 :

이건 괜찮아 :

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

그러나 성능을 위해 @attachments를 두 번 반복 할 필요가 없습니다.

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


답변

첨부 파일이

@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 쿼리를 트리거하지 않습니다.


답변

eager loading을 시도해 보셨습니까?

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


답변

where를 사용하여 필터링 할 수 있습니다.

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


답변

나는 이것에 대해 약간 다르게 할 것입니다. 필요한 항목 만 검색하고 여기에서 분할하도록 쿼리를 구성합니다.

따라서 쿼리를 다음과 같이 만드십시오.

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

그러면 깔끔하고 효율적인 방식으로 원하는 데이터를 얻을 수 있습니다.


답변