2016-09-13 4 views
0

Railsで作業しています。私はレシピフォームに原料フィールドを動的に生成するためにコクーンの宝石を取り入れています。 を使用して動作させることはできますが、カスタムネストされた属性ライターは使用できません。例えば、繭を組み込む前に、私のコードは次のように見えた:繭の宝石を使用するためにはRailsのカスタムネストされた属性ライターにallow_destroyオプションを組み込む方法

#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 

、私はingredients_attributesのための私の強いのparamsを変更して、私のレシピフォームおよびレシピモデルをリファクタリングする必要があり、それはです私に問題を与えている最後の部分。私はそれがライン

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

で動作させることができますが、私は代わりに私のカスタム属性ライターにオプションを組み込む方法を知っていただきたいと思います。リファクタリングされたコントローラとフォームコードを確認すると便利ですが、投稿することもできます。ありがとう。

+0

Canなぜあなたはそれをしたいのですか?あなたがモデルではなくコントローラに入れば、それはずっと面倒です。 – luissimo

+0

私はあなたの質問を理解していません。私はコントローラーに何も入れていません。コントローラーで変更されるのは強力なパラメーターだけです。他のすべては 'recipe.rb'ファイルにあります – TDB

+0

railsからネストされた属性の扱いを書き直す場合は、実際のレールコードが良いでしょう: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何千もの開発者が使用し、触れ、改善したコードを使用することに大きな利点があります。既に発見されているすべてのバグを想像してみてください。最初の実装は、既存のアイテムを削除するまで、非常に簡単でした。次は、アイテムが新規かどうか(作成するか)、既存のアイテムを更新するかをチェックします。次へ:空白の項目を無視する。次へ:特定のフィールドが埋められていないときを無視する。次へ:1対1の関係を処理する。言及しない:既知の標準を使用して他の宝石に依存しています。 – nathanvda

関連する問題