2012-05-10 2 views
0

레일 3.1을 기반으로 attr_accessible 속성의 동적 배열, 루비 나는 건물입니다 응용 프로그램에 Railscasts에게 에피소드 345 (HSTORE)을 적용하려고 1.9.2레일에 루비 -> 메타 프로그래밍 - has_many 관계

만들기 -이 문제는 HSTORE 중심이 아닙니다 ... Properties 해시를 직렬화하는 경우에도 실행됩니다. 여기 트위스트입니다, 지금

Class Product < ActiveRecord::Base 

has_many :properties 

%w[author rating runtime].each do |key| # *****--> PLEASE SEE BELOW! 
    attr_accessible key 
    scope "has_#{key}", lambda { |value| where("properties @> (? => ?)", key, value) } 

    define_method(key) do 
    properties && properties[key] 
    end 

    define_method("#{key}=") do |value| 
    self.properties = (properties || {}).merge(key => value) 
    end 
end 

* : 여기

내가에 대한 질문이 코드입니다. 제품 클래스에는 관리자가 작성시 지정하는 많은 특성이 있습니다. 이 작업은 Property라는 조인 된 모델에서 수행됩니다.

그래서 속성 배열 대신 Property라는 조인 된 has_many 모델을 검색하고 배열에 속성 ID 컬렉션이 채워지도록하고 싶습니다.

나는

self.properties.collect{ |property| "property_#{property.id}" }.each do |key| 

하지만이 작동하지 않습니다와 [저자 평가 런타임] 승 %의 선언 된 배열을 교체 시도! 속성 관계에 대한 정의되지 않은 메서드 오류가 발생합니다. 모델이 아직 인스턴스화되지 않았기 때문에 가정합니다. 프로그래밍에 익숙하지 않으며 메타 프로그래밍에 대해 전혀 모릅니다.

편집 -

... 그래서 손실 내가 after_find 후크로이 모든 이동 시도하고이 (. 다른 성공하지 못한 시도의 수십와 함께) 중 하나가 작동하지 않습니다 어떤 도움을 크게이다 고맙다!

+0

메소드 속성은 제품 인스턴스에서만 사용할 수 있습니다. @ product.properties의 의미를 완전히 바꾸고 싶습니까? (즉, has_many : properties를 제거합니다), 또는 일반적인 의미를 유지하고 그것을 어떤 식으로 보충하고 싶습니까? – RadBrad

+0

답장을 보내 주셔서 감사합니다. (정상적으로 @ product.properties를 쿼리 할 수 ​​있기를 원하기 때문에) 정상적인 의미를 유지하고 싶습니다.하지만 추가 할 수 있습니다. 예를 들어 제품 1에 속성 작성자와 등급이 지정된 경우에만이 인스턴스에 대한 액세스 가능 특성 목록에서 런타임 특성을 유지하고 싶습니다. 반면 제품에 가입을 통해 할당 된 모든 속성이있는 경우 모든 속성을 액세스 할 수 있도록 사용하고 싶습니다. –

답변

0

글쎄, 해킹 이틀 후, 나는 이것이 결국 알아 냈다고 생각합니다.

'사운드'에 대한 모든 피니언은 대단히 감사합니다! 한마디로

, 나는 위의 코드 블록을 포장했다 않았다 모두가 그렇게 같은 방법으로 (% 기호로 시작) :

def dynamic_accessible_and_setters(*details) 
    details.each do |key| # I placed the details variable here instead of the %w[] 
    attr_accessible key 
    scope "has_#{key}", lambda { |value| where("properties @> (? => ?)", key, value) } 

    define_method(key) do 
     properties && properties[key] 
    end 

    define_method("#{key}=") do |value| 
     self.properties = (properties || {}).merge(key => value) 
    end 
    end 
end 

을 그리고, 컨트롤러, 나는 단지의 방법이라고 클래스와 할당 된 속성의 배열 :

def edit 
    PRODUCT.dynamic_accessible_and_setters("author", "rating", "runtime") 
    ... 
end 

그리고 지금은 동적으로 구축 게터, 세터와 attr_accessible, 클래스의 각 인스턴스에 대한 사용자 정의 (또는, 그래서, 내가?!) 생각

이 도움이 되었기를 바랍니다. 이제는 여러 개의 DB 쓰기와 직렬화 및 하나의 쓰기의 성능 절충을 살펴 보겠습니다.