2016-09-16 1 views
0

'attributes'라는 테이블 열 중 하나에 배열을 저장하는 모델이 있습니다. 그래서 3 개 별도의 기록은 다음과 같습니다레일 4 Ruby Enumerable을 사용하여 배열을 사용하여 배열 쿼리

기록 1

MyModel.attributes = {Red, Furry, Stinky} 

기록 2

MyModel.attributes = {Red} 

기록 3

MyModel.attributes = nil 

기록 내가 전무를 포함한 다른 배열의이 배열을 조회하고 싶습니다 4

MyModel.attributes = {Blue, Furry, Sweet} 

. 결과는 쿼리 배열의 모든 특성과 특성 열이 nil 인 레코드가있는 레코드를 반환해야합니다.

query_array = [Blue, Furry] 

이 질의에 대한 답변은 기록 1, 레코드 3 및 레코드 4를 제공해야한다 - 단지 쿼리

MyModel.all.select {|m| m.attributes["Furry"] or m.attributes["Blue"] } 
나는 경우 다시, 그것은 현재 ALL을

을 찾고 아니에요, 나는이 작업을 수행 할 수 있습니다

하지만 배열을 동적으로 만들 수 m.attributes [ "특성"] handcode 않습니다. 모든 배열 항목을 요구하지 않고이 작업을 수행하는 방법을 알아낼 수는 없습니다. 단지 배열 항목과 속성이없는 레코드 만 있으면됩니다.

+0

어떤 유형의 데이터베이스를 사용하고 있습니까? 열의 형식은 무엇입니까? –

답변

1

attributes은이 이름이 이미 레일스 모델의 속성 해시 접근 자에 사용되었으므로이 열을 호출하면 안됩니다.

model_1.tags # => ['red', 'furry', 'stinky'] 
model_2.tags # => ['red'] 
model_3.tags # => nil 
model_4.tags # => ['blue', 'furry', 'stinky'] 

search_tags = ['red', 'blue'] 
MyModel.all.select do |model| 
    model.tags.nil? || (model.tags & search_tags).any? 
end 

당신은 할 수 : 나는 아래의 예는 tags

이 개명 태그의 교차가 어떤 태그가있는 경우 간단한 해결책은 (항상 그 기록을 포함) nil 확인하고 확인하는 것이다 또한 중첩 된 루프로 작성하십시오.

이것은 모두 루비 자체에서 수행됩니다. 레코드가 100_000 또는 1_000_000이면 DB에서 모두 가져오고 인스턴스화 한 다음 필터링합니다.

정확한 요구 사항과 사용중인 DB에 따라 더 쉽고 더 효과적인 솔루션을 찾을 수 있습니다.몇 가지 아이디어 :

  • 스토어 태그 별도의 테이블
  • 스토어는 쉼표로 구분 된 문자열로 태그와 쿼리 '처럼'
  • 사용이 JSON 데이터 형을 POSTGRES 및 쿼리 포스트 그레스는
를 제공하는 기능을 사용
+0

감사합니다 ... 실제로 속성이라고하지는 않지만 이름이 혼란 스럽기 때문에 자리 표시 자 이름을 추가했습니다. 그래도 알려 줘서 고마워. 그리고 그것을 더 잘하는 방법에 대한 조언은 .... 당신 말이 맞아요. 그것은 태깅과 같습니다. 나는 리팩토링 ... – NothingToSeeHere

-1

당신은 당신이해야 할 query_array에 더 많은 항목을 추가하고, 지금이

query_array = [Furry, Blue] 
query_string = query_array.map{|query| "m.attributes[#{query}]" }.join(" || ") 

#=> "m.attributes[Furry] || m.attributes[Blue]" 

MyModel.all.select {|m| eval(query_string) } 

을 시도 할 수 있습니다.

+0

절대'eval'을 절대로 사용하지 마십시오. 그것은 악의적이고 위험하며 디버깅하기가 어렵고 읽을 수 없습니다. –

+0

추가 정보를 잊어 버렸습니다. 보안 문제를 게시 할 수 있습니다. –

관련 문제