Bick
Bick

Reputation: 18521

ruby on rails - presenting many to many relation

I have recipe and ingredient in a many to many relation.

I have defined the following commands in my presentation.

<div>
  <%= render :partial => 'ingredients/form',
             :locals => {:form => recipe_form} %>
</div>

the partial begins with

<%= form_for(@ingredient) do |ingredient_form| %>

but received @ingredient nill. Then I tried

<%= recipe_form.fields_for :ingredients do |builder| %>
    <%= render 'ingredient_fields', f: builder %>
<% end %>

where my render was

<p class="fields">
  <%= f.text_field :name %>
  <%= f.hidden_field :_destroy %>
</p>

but nothing was printed. then I tried

<% @recipe.ingredients.each do |ingredient| %>
    <%= ingredient.name %>
<% end %>

and only then all of the ingredients were printed. What was I doing wrong in the previous tries ? Thank you.

my ingredient recipe relation defined as follows

 class Ingredient < ActiveRecord::Base
   has_many :ingredient_recipes
   has_many :recipes, :through => :ingredient_recipes
   ...

 class Recipe < ActiveRecord::Base
   has_many :ingredient_recipes
   has_many :ingredients, :through => :ingredient_recipes
   ...

   accepts_nested_attributes_for :ingredient_recipes  ,:reject_if  => lambda { |a| a[:content].blank?}


 class IngredientRecipe < ActiveRecord::Base
  attr_accessible :created_at, :ingredient_id, :order, :recipe_id
  belongs_to :recipe
  belongs_to :ingredient
 end

Upvotes: 0

Views: 134

Answers (1)

iHiD
iHiD

Reputation: 2438

You don't exactly specify what you are trying to do, so I am presuming you have a page that shows a recipe, with many ingredients that can be edited and added to. In your controller you have something like:

class RecipeController < ApplicationController
  def edit
    @recipe = Recipe.find(params[:id]
  end
end

I am also presuming that you are looking to have a form that post backs to the create action. I therefore think you want a form like this:

<%= form_for @recipe do |form| %>

  <%= label_for :name %>
  <%= text_field :name %>

  <%= form.fields_for :ingredients do |ingredients_fields| %>
    <div class="ingredient">
      <%= f.text_field :name %>
      <%= f.hidden_field :_destroy %>
    </div>
  <% end %>

<% end %>

Also, change your recipe to accept nested attributes for ingredients, not ingredient_recipes:

class Recipe < ActiveRecord::Base
   has_many :ingredient_recipes
   has_many :ingredients, :through => :ingredient_recipes
   ...

   accepts_nested_attributes_for :ingredients, :reject_if  => lambda { |a| a[:content].blank?}

And finally, add attr_accessible for your content:

class Ingredient < ActiveRecord::Base
  attr_accessible :content
  ...

Does that work for you?

Upvotes: 1

Related Questions