2013-04-19 4 views
6

는 다른 열 중 하나의 내가 단지 FooUser의 이름을 원하는 가정 해 봅시다, 그리고 ActiveRecord 연결에서 특정 열만 요청할 수 있습니까?

def Foo 
    has_one :user 
end 

을 고려하십시오. 그래서 하나의 열을 얻을 수있는 연결을 사용하기 위해 교묘 한 방법이 내가

SELECT name FROM "users" WHERE "prices"."id" = 123 

를 원하지만 일을 foo.user.name

SELECT * FROM "users" WHERE "prices"."id" = 123 

줄 것이다? 이로부터 단지 값을 반환합니다

User.select(:name).where(...) 

: 당신은 당신처럼 ALL 기타 사항 서보 -OFF 방법을 사용하여 선택하고 싶은 열을 지정할 수 있습니다

User.where(id: foo.user_id).pluck(:name).first 

답변

4

을 일반적으로 :하지 않을 경우, 그럼 내가해야 할 이름 열. 이를 연계로 연결할 수는 있지만 인스턴스로 연결할 수는 없습니다. 그래서, meagar가 다른 대답 (Mori의 삭제 된 응답 포함)을 downvoting하여 매우 적극적으로 지적했듯이, has_one 관계에서 (이 경우 연관이 없기 때문에) 협회에 연결할 수 없습니다. 그러나이 같은 사용자 지정 범위를 만들 수 :

class Foo < ActiveRecord::Base 
    has_one :bar 
    scope :bar_name, lambda {Bar.select(:name).where(:foo_id=> id)} 
end 

을 당신이 그것을 조정할해야 할 수도 있지만, 일반적으로 그 방법을 말하는 것은 당신이 같은 것을 할 수 있도록 할 수 있도록 위가 안된 :

foo.bar_name 

... Bar의 모든 열을로드하지 않고.

+0

이 범위가 대표적일까요? 스코프는, 일반적으로, ActiveRecord :: Relation를 하늘 또는 안쪽으로 돌려줍니다. 메서드가 더 적절할 것입니다 (또는 위임 하시겠습니까?) – MrYoshiji

+0

이것은 ActiveRecord 쿼리 메서드의 체인이므로 관계를 반환한다고 생각합니다. 대신 Bar 클래스에 작성된 관계를 반환한다는 점만이 이상한 점입니다 Foo 클래스의 -하지만 일단 당신이'something.otherthing.where()'에 가면 어쨌든 그것을하는 것이 좋습니다. 이 방법을 정의하는 것도 좋은 방법입니다. 저는 이런 식으로 할 필요가 전혀 없기 때문에 어떤 것이 더 낫거나 왜 그런지에 대한 기준 틀이 없습니다. – Andrew

1

아니요, has_one의 경우에는 has_many의 경우 예입니다.

has_one 연결에 대해 반환 된 개체는 has_many과 같이 select과 같은 추가 메서드를 연결할 수있는 범위가 아닙니다. 모델의 실제 인스턴스이며, 인스턴스화하려면 반드시 select *이 필요합니다.

이름 만 선택하려는 경우 User 모델에 직접 액세스하고 select을 사용해야합니다. 당신의 Foo 많은 users이있는 경우

반대로, 당신은 실제 액티브 협회가 아닌 모델의 인스턴스가 될 것 foo.users로, foo.users.select("name") 또는 다른 체인 가능 방법 중 하나를 사용할 수 있습니다.

관련 문제