2011-04-11 3 views
1

안녕 : 액티브 찾아 전화를하려고액티브 관계와 다음을 수행하려고 할 때 나는 최근이에 실행 된 개체 모델

posts = User.first.posts 
posts.find {|p| "p.id" == 123} => ActiveRecord::RecordNotFound: Couldn't find Post without an ID 

. 기대하는 바 :

posts.find(123) 

하지만 DB를 다시 쿼리하고 싶지 않습니다.

posts.to_a.find {|p| "p.id" == 123} 

그래도 나는 posts.class에 따라 배열을 처리했다 : 그래서 할 필요가있다. 왜 to_a를 호출해야합니까? 은 (아마도) 배열의 인스턴스 인 경우

posts.class => Array 
posts.superclass => ActiveRecord::Base 

이유는 게시물에 슈퍼 클래스를 호출 할 수 있습니다 이유는 액티브 :: 자료를 반환합니까? 또한

:

posts.ancestors.include? ActiveRecord::Base => false 

왜 액티브 :: 자료는 게시물 배열의 슈퍼 false 인 경우이다?

하나 더. 내가하는 일 :

posts.instance_methods(false) 

관계 클래스의 인스턴스 메소드, 즉 게시를 반환합니다. 게시물이 배열이기 때문에 이상하게 보입니다. 나는 "일반"배열을 만들 마찬가지로 경우 :

a = [1, 2] 
a.instance_methods(false) => NoMethodError: undefined method `instance_methods' for [1, 2]:Array 

그래서 배열은 액티브 관계 쿼리를 통해 반환

배열과 같은 종류이지만,이 액티브 상속처럼하지 ... 그것은 보이지만 그렇지 않습니다 ...또는 뭔가. 내가 Ruby 객체 모델을 확실하게 이해하고 있다고 생각했을 때 :) ActiveRecord를 살펴 보는 것만으로도 도움이 될 것입니다. 나는 잘 모르겠다. 그래서 나는 내가 추측하는 것을 요구하고있다.

이것은 호기심에 불과합니다. 모든 도움말/지침은 인정됩니다

+1

의 자손입니다. 문자열을 블록의 int와 비교하는 이유는 무엇입니까? 왜'posts.find {| p | "p.id"== 123}'대신에? – Geo

+0

네, 그건 오타였습니다. 그것을 지적 해 주셔서 감사합니다 – jgoggles

답변

0

find 메서드는 ActiveRecord :: Base 클래스에서만 사용할 수 있습니다.이 메서드는 인스턴스 메서드가 아니라 클래스 메서드입니다.

예, 정확히 배열은 아니지만 Enumerable처럼 작동합니다. 선택 다른 배열을 반환하기 때문에

이 경우 당신은 단지 하나 개의 요소로 될, 마지막에

posts.select{|p| p.id == 123}.first 

선택 내가 추가 한 좁은 방을 사용할 수 있습니다.

희망이 도움이됩니다.

+1

올바른 방법은'select'보다는'select'를 사용하는 것입니다. 왜냐하면'detect'는 그것이 나오는 첫 번째 요소를 반환하고 찾고있는 것을 멈추게됩니다. 그냥 도움이되는 FYI. –

0

Enumerable에서 원하는 #find 메서드를 덮어 쓰는 것 같습니다. ActiveRecord::Base입니다. 이것이 겹쳐 써진 find 메소드가없는 배열로 변환해야하는 이유입니다.

posts.detect {|p| p.id == 123} 

finddetect의 별칭이지만 다시 posts에서 얻을 액티브 수집 프록시에 find 방법으로 그림자가되어

2

당신은 할 수 있습니다. 게시물 포스트 개체의 컬렉션이 아닌 ActiveRecord::Base의 후손이기 때문에

0
posts.ancestors.include? ActiveRecord::Base => false 

은 False입니다. 소식 모음의 개별 항목은 모두 ActiveRecord::Base

관련 문제