2016-09-13 7 views
0

레일에서 작업하면서, cocoon gem을 통합하여 레시피 양식에 성분 필드를 동적으로 생성합니다. 을 사용하지만 사용자 정의 중첩 속성 작성자를 사용하지 않고 작동하도록 할 수 있습니다. 예를 들어, 누에 고치를 통합하기 전에, 내 코드는 다음과 같이보고 :allow_destroy 옵션을 레일스의 사용자 정의 중첩 속성 작성기에 통합하는 방법

, 나는 ingredients_attributes 내 강력한 PARAMS을 수정하고 내 레시피 형태와 조리법 모델을 리팩토링해야하고, 그것은이다 고치 보석을 사용하려면
#recipe.rb 
class Recipe 
# name:string 
    has many :ingredients 
    # accepts_nested_attributes_for :ingredients 

    # the method below should do exactly the same thing as accepts_nested_attributes_for 

    def ingredients_attributes=(attributes) 
    attributes.each do |i, ingredient_hash| 
     self.ingredients.build(ingredient_hash) 
    end 
    end 

end 


#ingredient.rb 
class Ingredient 
    # name:string, price:integer 
    belongs_to :recipe 
end 



#recipes_controller.rb (just the params part) 
def recipe_params 
    params.require(:recipe).permit(:name, ingredients_attributes: [:name, :price]) 
end 

나에게 문제가되는 마지막 부분. 내가 그걸로 작동하도록 할 수 있습니다

accepts_nested_attributes_for :ingredients, reject_if: :all_blank, allow_destroy: true 

하지만 내 사용자 지정 속성 작성기에 옵션을 통합하는 방법을 알고 싶습니다. 리팩토링 된 컨트롤러 및 양식 코드를 보는 것이 도움이된다면 게시 할 수도 있습니다. 감사.

+0

Can 왜 그걸하고 싶니? 모델이 아닌 컨트롤러에 넣으면 훨씬 더 혼란 스럽습니다. – luissimo

+0

질문이 이해가 가지 않습니다. 나는 컨트롤러에 아무것도 넣지 않을거야. 내 컨트롤러에서 변경된 유일한 것은 강력한 매개 변수입니다. 다른 모든 것은'recipe.rb' 파일에 있습니다. – TDB

+0

레일에서 중첩 된 속성 처리를 다시 작성하는 경우, 좋은 시작점은 실제 레일 코드입니다 : https://github.com/rails/rails/blob/ 0fe76197d2622674e1796a9a000995a7a1f6622b/activerecord/lib/active_record/nested_attributes.rb # L319 – nathanvda

답변

0

rails 대신 자신의 ingredients_attributes= 메서드를 정의 할 때 유용하다고 확신하는 경우 을 사용하는 것이 더 강력합니다.

그러나 일부 사용 사례에 대한 자신의 ingredients_attributes=을 정의해야하는 경우, 다음과 allow_destroy 달성 할 수 :

class RecipesController < ApplicationController 
    def recipe_params 
    params.require(:recipe).permit(:name, ingredients_attributes: [:name, :price, :_destroy]) 
    end 
end 

class Recipe < ActiveRecord::Base 
    def ingredients_attributes=(attributes) 
    attributes.each do |i, ingredient_hash| 
     if ingredient_hash[:_destroy].present? 
     #include logic to destroy the associated record 
     #both for new records and existing records 
     else 
     #you also need to make sure you address the 
     #case for existing records and don't just build 
     self.ingredients.build(ingredient_hash) 
     end 
    end 
    end 
end 

자신을 구현하는 경우, ingredients_attributes=의 위의 설명에서 언급 한 바와을 ingredients_attributes= 대신 을 사용하는 경우 기존 레코드 (삭제 표시 여부), 새 레코드 (삭제 표시 여부) 등 모든 사용 사례를 처리해야합니다.

+0

이 예제에서는 사용자 정의 작성기에서 해당 옵션을 구현하는 방법을 배우는 것 외에는 accepts_nested_attributes_for를 사용하지 않을 이유가 없습니다. – TDB

+0

도움 주셔서 감사합니다. 여전히 작동 방법을 얻는 데는 운이 없지만 계속 시도 할 것입니다. 나는이 작업을하기 위해 누에 고치가 백그라운드에서하고있는 것을 정확히 이해할 필요가 있다고 생각합니다. 또한,이 특별한 예제에서는 커스텀 작가에서 그 옵션을 구현하는 방법을 단순히 배우는 것 외에는'accepts_nested_attributes_for'를 사용하지 않을 이유가 없습니다. 내 Rails 강사 중 한 명은 자신의 중첩 된 속성 작성자를 작성하는 것이 거의 항상 더 낫다고 주장했습니다. 그 이유는 정확히 무엇을하고 있는지, 그리고 필요에 따라 더 커스터마이징하는 방법을 알기 때문입니다. 이제 이론을 테스트하십시오! – TDB

+0

Imho는 수천 명의 개발자가 사용하고 손쉽게 수정하고 개선 한 코드를 사용하면 큰 이점이 있습니다. 이미 발견 된 모든 버그를 상상해보십시오. 초기 구현은 기존 항목을 삭제할 때까지 매우 쉽습니다. 다음 : 항목이 새 것인지 (작성) 또는 기존 (갱신)인지 점검하십시오. 다음 : 빈 항목 무시. 다음 : 특정 필드가 채워지지 않을 때를 무시합니다. 다음 : 일대일 관계를 처리합니다. 말할 것도없이 : 알려진 표준을 사용하면 다른 보석들이 의지합니다. – nathanvda