Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

has_many build method, Rails

Another newbie question.

The goal: each ingredient can have zero or more unit conversions tied to it. I want to put a link to creating a new unit conversion on the page that shows a specific ingredient. I can't quite get it to work.

Ingredient Model:

class Ingredient < ActiveRecord::Base
   belongs_to :unit
   has_many :unit_conversion
end

Unit Conversion Model:

class UnitConversion < ActiveRecord::Base
  belongs_to :Ingredient
end

Unit Conversion Controller (for new)

def new
    @ingredient = Ingredient.all
    @unit_conversion = @ingredient.unit_conversions.build(params[:unit_conversion])
    if @unit_conversion.save then
        redirect_to ingredient_unit_conversion_url(@ingredient, @comment)
        else
            render :action => "new"
        end
  end

Relevant Routes:

  map.resources :ingredients, :has_many => :unit_conversions

Show Ingredient Link:

<%= link_to 'Add Unit Conversion', new_ingredient_unit_conversion_path(@ingredient) %>

This is the error:

 NoMethodError in Unit conversionsController#new

undefined method `unit_conversions' for #<Array:0x3fdf920>

RAILS_ROOT: C:/Users/joan/dh
Application Trace | Framework Trace | Full Trace

C:/Users/joan/dh/app/controllers/unit_conversions_controller.rb:14:in `new'

Help! I'm all mixed up about this.

like image 925
Joan Avatar asked Jan 03 '10 01:01

Joan


2 Answers

Unit Conversion Controller for new and create should be:

def new
  @ingredient = Ingredient.find(params[:ingredient_id])    
  @unit_conversion = @ingredient.unit_conversions.build
end

def create
  @ingredient = Ingredient.find(params[:ingredient_id])    
  @unit_conversion = @ingredient.unit_conversions.build(params[:unit_conversion])

  if @unit_conversion.save
    flash[:notice] = "Successfully created unit conversion."
    redirect_to ingredient_unit_conversions_url(@ingredient)
  else
    render :action => 'new'
  end
end

Also, this screencast is a nice resource for nested resources.

like image 113
Chandra Patni Avatar answered Sep 28 '22 04:09

Chandra Patni


has_many :unit_conversion

Should be pluralized since you're calling it with

@unit_conversion = @ingredient.unit_conversions.build

your controller

def new
  @ingredient = Ingredient.all

should be calling #new to setup a new Ingredient or #find to grab an existing Ingredient.

@ingredient = Ingredient.new       # returns a new Ingredient

or

@ingredient = Ingredient.find(...) # returns an existing Ingredient

Which one you choose is up to your requirements.

Also, this is a typo, right?

belongs_to :Ingredient

You might want to lowercase :ingredient

like image 40
nowk Avatar answered Sep 28 '22 05:09

nowk