Метод сборки has_many, Rails
Другой вопрос новичков.
Цель: каждый ингредиент может иметь нулевое или большее количество конверсий единиц, привязанных к нему. Я хочу поместить ссылку на создание нового преобразования единиц на странице с конкретным ингредиентом. Я не могу заставить его работать.
Модель ингредиента:
class Ingredient < ActiveRecord::Base
belongs_to :unit
has_many :unit_conversion
end
Модель преобразования единиц измерения:
class UnitConversion < ActiveRecord::Base
belongs_to :Ingredient
end
Контроллер преобразования единиц (для новых)
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
Соответствующие маршруты:
map.resources :ingredients, :has_many => :unit_conversions
Показать ссылку на компонент:
<%= link_to 'Add Unit Conversion', new_ingredient_unit_conversion_path(@ingredient) %>
Это ошибка:
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'
Помощь! Я все перепутал.
Ответы
Ответ 1
Контроллер преобразования единиц для new
и create
должен быть:
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
Кроме того, этот screencast является хорошим ресурсом для вложенных ресурсов.
Ответ 2
has_many :unit_conversion
Должно быть плюрализовано, поскольку вы вызываете его с помощью
@unit_conversion = @ingredient.unit_conversions.build
ваш контроллер
def new
@ingredient = Ingredient.all
должен вызывать #new
для установки нового Ингредиента или #find
для захвата существующего Ингредиента.
@ingredient = Ingredient.new # returns a new Ingredient
или
@ingredient = Ingredient.find(...) # returns an existing Ingredient
Какой из выбранных вами вариантов соответствует вашим требованиям.
Кроме того, это опечатка, правильно?
belongs_to :Ingredient
Возможно, вы захотите ввести строчные буквы :ingredient