2010-02-01 2 views
6

다른 형식의 파일을 스트림에 추가 할 수있는 양식이 있습니다. 따라서 스트림은 많은 파일로 구성되어 있습니다.이 파일은 XML 파일이지만 기본적으로 다른 스키마가 있습니다. 사용자가 원하는 파일을 추가 할 수있는 양식이 하나 있는데, STI (데이터가 이미 테이블에있을 때 유용함)를 사용하고 있는데, 문제는 데이터를 테이블에 추가하는 것입니다.하나의 형식을 사용하는 STI 레일

양식에는 1 개의 입력 필드가 있으며 업로드하려는 파일을 선택할 수있는 file_field 만 있습니다. 나는 올바른 객체를 인스턴스화 할 수없는 하나의 형식만을 가지고 있기 때문에 프로그래밍으로해야하고 .. 어떻게해야할지 모르겠다.

가능한 유형으로 드롭 다운을 추가하고 양식을 제출할 때 유형 속성이 제공되므로 레일스가 유형의 객체 쓰기를 인스턴스화 할 수 있도록 '유형'필드를 호출 할 수 있습니까?

무엇이 최선의 방법입니다. 레일 2.3.4를 실행 중입니다.

답변

3

을 나는 http://coderrr.wordpress.com/2008/04/22/building-the-right-class-with-sti-in-rails/#comment-1826

class GenericClass < ActiveRecord::Base 
    class << self 
    def new_with_cast(*a, &b) 
     if (h = a.first).is_a? Hash and (type = h[:type] || h['type']) and (klass = type.constantize) != self 
     raise "wtF hax!!" unless klass < self # klass should be a descendant of us 
     return klass.new(*a, &b) 
     end 

     new_without_cast(*a, &b) 
    end 
    alias_method_chain :new, :cast 
    end 
end 
,536,913에서 해결책을 발견

최소의 코드로 저에게 큰 도움이되었습니다. hackish인지 아닌지는 잘 모르겠지만 작동합니다. 나는 코드의 유일한 10ish 라인을 좋아했다.

+1

더하기 1 "wtF hax !!" – tybro0103

0

얼마나 많은 유형이 있는지 알 수 없지만 이전에는 여러 유형의 컨트롤러와 뷰를 별도로 사용했습니다. 이렇게하면 기본 클래스의 새 객체를 만들지 않고 유형을 설정하려고 할 때 기본 클래스에서 상속 한 모델 만 사용하면됩니다. 리소스에 대한 각각의 새/편집 페이지는 form_for 블록에서 공유 부분을 렌더링 할 수 있습니다. partial은 file_field를 포함합니다.

양식을 제출할 때 올바른 컨트롤러로 이동하여 올바른 resource.new를 호출하면 모든 것이 정상입니다.

단점은 물론 더 많은 파일과 "새 파일 추가"에 링크하는 페이지는 "새 파일 유형 추가", "새 파일 유형 추가"등과 같은 여러 링크를 추가해야합니다.

형태로 유형을 설정하는 경우 작동 여부는 확실하지 않지만 의심 스럽지만 시도해보십시오 (Google에 알려주세요). 해당 유형을 select_tag 아래로 드롭 다운 할 수 있으며 변경되면 Javascript를 사용하여 양식의 작업 위치를 변경할 수 있습니다.

편집과 내가 & 내가 의심이 솔루션을 좋아하는

하지 주위에 기본 작업을 추가는 결코 최고의 의미하지만, 당신이 정말로 별도의 컨트롤러를 원하는하지 않는 경우에 당신이 당신을 작동하는 데 필요한 의해 이런 식으로 뭔가를 할 수 :

class XmlFile < ActiveRecord::Base 
end 

class XmlFileTypeA < XmlFile 
end 

class XmlFileTypeB < XmlFile 
end 

def create 
    # Leaving this case statement in the controller for simplicity but you probably want to move this to the model 
    case params[:chosen_xml_type] 
     when "file_type_a" 
     @item = XmlFileTypeA.new(params) 
     when "file_type_b" 
     @item = XmlFileTypeB.new(params) 
     else 
     raise "Unknown file type!" 
     etc 
    end 
end 
+0

그래요. 저는 현재 각각 두 개의 문서 유형을 가지고 있지만, 더 빠르게 될 수는 있지만, 각각 별도의 컨트롤러를 만드는 것을 피하고 싶었습니다. 레일스는 STI를 구현하는 것이 너무 단순 해 보이지만, 정보를 검색하는 것만으로도 STI 구현을위한 '새로운'형태의 예제를 찾을 수 있습니다. – Rabbott

+0

내 편집 된 게시물을 보면, 뷰를 렌더링하는 새로운 액션은 @xml_file = XmlFile.new를 만들 것이고, 생성 액션은 사용자 선택에 따라 올바른 파일 유형을 생성합니다. 그게 진흙으로 분명 희망!? – tsdbrown

+0

업데이트에 대한 감사의 말씀입니다. 컨트롤러가 실제로 객체를 인스턴스화하는 것이므로 거기에 머물러 있지 않아도됩니까? 나는이 모든 연구가 끝나면, 내가 바라는 것은 classify.constanize.new 또는 이와 비슷한 것을 호출 할 수있는 방법이라고 생각한다. 드롭 다운의 값을 사용하여 해당 유형의 객체를 만들 수 있습니다. – Rabbott