1

私はレシピマネージャを最初のレールアプリとして構築しています。私はこれを基にした多対多のネストされたモデルを持っています。ERD。理想的には、単一のフォームでレシピを作成できるフォームを作成したいと考えています。また、ユーザーが1つのテキストフィールドに成分とステップを書き込んだり貼り付けたりできるようにしたいと思います。下のコードでは、フォーム内のcrで区切られたリストを解析してこれを試みる仮想属性があります。簡単なネストされた、has_many:through、多対多のフォームをRails 3.1に書くには?

私は成分を書き込むときに "readonly" has_many throughエラーが発生します。私は、私がオフラインになった優れたヘルプに基づいて、私の参加が適切にセットアップされていないことを理解しています。

簡単にするために、最初のステップまたはすべてのステップに成分リストを割り当てたいと思います。 仮想属性を使用して結合モデルを手動で作成するようにコードを記述するにはどうすればよいですか?

私の4つのモデル:ingredient.rb

recipe.rb

class Recipe < ActiveRecord::Base 
     has_many :steps, :dependent => :destroy 
     has_many :stepingreds, :through => :steps 
     has_many :ingredients, :through => :stepingreds 
     validates_presence_of :name, :description 
     attr_writer :step_instructions, :ingredient_names 
     after_save :assign_steps, :assign_ingredients 

     def step_instructions 
     @step_instruction || steps.map(&:instruction).join("\n") 
     end 

     def ingredient_names 
     @ingredient_name || ingredients.map(&:name).join("\n") 
     end 

    private 

    def assign_steps 
     if @step_instructions 
      self.steps = @step_instructions.split(/\n+/).map do |instruction| 
      Step.find_or_create_by_instruction(instruction) 
      end 
     end 
    end 

     def assign_ingredients 
     if @ingredient_names 
      self.ingredients = @ingredient_names.split(/\n+/).map do |name| 
      Ingredient.find_or_create_by_name(name) 
      end 
     end 
     end 
    end 

step.rb

class Step < ActiveRecord::Base 
     #attr_accessible :recipe_id, :number, :instructions 
     belongs_to :recipe 
     has_many :stepingreds, :class_name => 'Stepingred' 
     has_many :ingredients, :through => :stepingreds 
    end 

stepingred.rb

class Stepingred < ActiveRecord::Base 
     belongs_to :ingredient 
     belongs_to :step, :class_name => 'Step' 
    end 
class Ingredient < ActiveRecord::Base 
     has_many :stepingreds 
     has_many :steps, :through => :stepingred 
     has_many :recipes, :through => :steps 
    end 

そしてここでは、私のストリップダウン形式です:

<%= form_for @recipe do |f| %> 
     <%= f.error_messages %> 
     <p> 
     <%= f.label :name %><br /> 
     <%= f.text_field :name %> 
     </p> 
     <p> 
     <%= f.label :description %><br /> 
     <%= f.text_area :description, :rows => 4 %> 
     </p> 
     <p> 
     <%= f.label :ingredient_names, "Ingredients" %><br /> 
     <%= f.text_area :ingredient_names, :rows => 8 %> 
     </p> 
     <p> 
     <%= f.label :step_instructions, "Instructions" %><br /> 
     <%= f.text_area :step_instructions, :rows => 8 %> 
     </p> 
     <p><%= f.submit %></p> 
    <% end %> 

私のデータベーススキーマ:

ActiveRecord::Schema.define(:version => 20110714095329) do 
     create_table "ingredients", :force => true do |t| 
     t.string "name" 
     t.datetime "created_at" 
     t.datetime "updated_at" 
     end 
     create_table "recipes", :force => true do |t| 
     t.string "name" 
     t.text  "description" 
     t.datetime "created_at" 
     t.datetime "updated_at" 
     end 
     create_table "stepingreds", :force => true do |t| 
     t.integer "recipe_id" 
     t.integer "step_id" 
     t.integer "ingredient_id" 
     t.float "amount" 
     t.datetime "created_at" 
     t.datetime "updated_at" 
     end 
     create_table "steps", :force => true do |t| 
     t.integer "recipe_id" 
     t.integer "number" 
     t.text  "instruction" 
     t.datetime "created_at" 
     t.datetime "updated_at" 
     end 
    end 

あなたが何か提案を持っているか、サンプルコードの別の部分をお勧めすることができます場合は私に知らせてください私は後にこのアプリをモデル化することができます。

答えて

2

@recipeオブジェクトを使用して関連オブジェクトを作成できるようにするには、accepts_nested_attributes_for :ingredients, :stepingreds, :stepsRecipe.rbに追加する必要があります。

http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

+0

ありがとうございました。私は 'accepts_nested ...'を追加し、 'Ingredient.find_or_create_by_name(name)'を 'self.steps.create(:stepingreds => [{:ingredients => {:name => name}}])に変更しました。 APIの読み取り。私は今、エラーを取得します。 'NameError in RecipesController#未定義のローカル変数またはメソッド' attribute 'を作成します。# 'ネストされた配列に正しく書き込んでいますか?そのエラーは何かを伝えますか?ログには、Ingredientsテーブルに挿入しようとすることは記載されていないので、レコードを不適切に作成する必要があります。再度、感謝します。 – JHo

+0

答えを受け入れることを忘れないでください – imjp

+0

アプリであなたの完全なコードを見ることなくこのエラーの原因を言うのは難しいです。通常、そのエラーはスタックトレースに行番号を指定しています。アプリケーションのコピーをgithubリポジトリにプッシュして、それを適切に再現して見てください。 – Joey

関連する問題