단일 열의 값을 배열로 가져 오는 방법


80

지금은 단일 데이터 열을 선택하기 위해 다음과 같은 작업을 수행하고 있습니다.

points = Post.find_by_sql("select point from posts")

그런 다음 메서드에 전달하면 메서드가 독립적으로 유지되기를 원하며 이제 메서드 내에서 hash.point를 호출해야합니다. 이것을 배열로 신속하게 변환하고 데이터 세트를 내 메소드로 전달하는 방법 또는 더 나은 방법이 있습니까?

답변:


190

Rails 3.2에는이를위한 pluck 메소드 가 있습니다.

다음과 같이 :

Person.pluck(:id) # SELECT people.id FROM people
Person.pluck(:role).uniq # unique roles from array of people
Person.distinct.pluck(:role) # SELECT DISTINCT role FROM people SQL
Person.where(:confirmed => true).limit(5).pluck(:id)

유니크와 구별의 차이점


배열은 pluck으로 쿼리 결과의 순서를 어떻게 상속 할 수 있습니까?
franklin stine

3
Post.order (: score) .pluck (: score)가 해결책입니다. 감사.
franklin stine 2012 년

6
ID를 뽑으려면 특별한 방법이 있습니다 : Person.ids.
shock_one 2014 년

또한 어니 밀러의 보석 발륨 들여다 github.com/ernie/valium 여러 열을 이전 레일에있어 또는 원하는 특히
제임스 다니엘스

Rails 5.0부터는 distinct대신 uniq다음 을 사용 하는 것이 좋습니다 . soPerson.distinct.pluck(:role)
David

15

pluck@alony가 제안한 방법을 사용해야합니다 . Rails 3.2 이전에 멈춘 경우 ActiveRecord select메서드를 다음과 함께 사용할 수 있습니다 Array#map.

Post.select(:point).map(&:point)
#=> ["foo", "bar", "baz"] 

.map{|x| x.title}하지만 Ruby 1.9 이전 Symbol#to_proc에는 (단항 &연산자로 별칭이 지정됨 ) 이전 버전의 Ruby에서 정의되지 않았기 때문에 해야 합니다.


감사. 나는 당신이 새로운 Pluck 방법에 대해 논평하는 것을 보았다. 그것으로 똑같이 할 수 있습니까?
franklin stine 2012 년

예, @alony의 답변을주의 깊게 읽으면 그녀가 이미이를 수행하는 예제가 포함되어 있음을 알 수 있습니다.
Patrick Oscity 2012 년

5

select_values의 정의가 보이면 'map (& : field_name)'을 사용합니다.

  def select_values(arel, name = nil)
    result = select_rows(to_sql(arel), name)
    result.map { |v| v[0] }
  end

배열의 모든 필드 값을 수집하는 일반적인 Rails 방법은 다음과 같습니다.

points = Post.all(:select => 'point').map(&:point)

좋은 지적. 감사합니다. 이것은 훌륭하게 작동하며 Post.select 예제와 달리 주문 및 기타 사항을 쿼리에 적용 할 수 있습니다.
franklin stine 2012 년

동의하지 않습니다, @franklinstine : Post.select(:point).limit(1)수행 SELECT point FROM "posts" LIMIT 1하는 Post.all(:select => :point).limit(1)동안 NoMethodError. 내가 틀렸다면 나를 바로 잡아주세요.
Patrick Oscity 2012 년

귀하의 의견에 동의합니다. 하지만 점점 아니에요 어디에 사용하는 게시물에 언급 : Post.all (: 선택 => : 점)으로 제한 할 (1) 당연히 그것을 줄 것이다 오류 "정의되지 않은 메서드`제한 '"
비크

@franklinstine은, 난 그냥이 사실이 아니라는 것을 명확하게하고 싶었 후 그는 다른 문을 체인 수 있기 때문에 그가 당신의 방법을 선호했다
패트릭 Oscity을

네 @padde 당신이 잘못 추론했습니다. 나는 여전히 주문 및 Post.all (: select => 'score', : order => 'score ASC'). map (& : score)와 같은 다른 쿼리 문을 적용 할 수 있다고 말하고있었습니다.
franklin stine

2
points = Post.all.collect {|p| p.point}

2
이것은 작동하지만 데이터베이스에서 모든 필드를 선택한 다음 Ruby에서 결과를 필터링하는 반면 select문은 지정된 열만 가져옵니다.
Patrick Oscity 2012 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.