Я пытаюсь построить приложение рецепт-хранитель с тремя основными моделями:Как ссылаться на существующий экземпляр модели во вложенной форме Rails?
Рецепт - рецепт для конкретного блюда
Ингредиент - список ингредиентов, проверенными на уникальность
Количество - Соединительный стол между ингредиентом и рецептом, который также отражает количество конкретного ингредиента, необходимого для конкретного рецепта.
Я использую вложенную форму (см ниже), который я построил, используя удивительный Railscast на вложенных форм (Part 1, Part 2) для вдохновения. (Моя форма в некотором смысле более сложна, чем руководство, из-за потребностей этой конкретной схемы, но я смог заставить ее работать аналогичным образом.)
Однако, когда моя форма отправлена, все и вся перечисленные ингредиенты создаются заново, и если ингредиент уже существует в БД, он не подтверждает валидность уникальности и препятствует созданию рецепта. Общее сопротивление.
Так что мой вопрос: Есть ли способ, чтобы представить эту форму, так что если ингредиент существует, имя которого совпадает с одним из моих полей, имя ингредиент, он ссылается на существующий компонент вместо того, чтобы пытаться создать новый с одно и то же имя?
специфика кода ниже ...
Recipe.rb
В:
class Recipe < ActiveRecord::Base
attr_accessible :name, :description, :directions, :quantities_attributes,
:ingredient_attributes
has_many :quantities, dependent: :destroy
has_many :ingredients, through: :quantities
accepts_nested_attributes_for :quantities, allow_destroy: true
В Quantity.rb
:
class Quantity < ActiveRecord::Base
attr_accessible :recipe_id, :ingredient_id, :amount, :ingredient_attributes
belongs_to :recipe
belongs_to :ingredient
accepts_nested_attributes_for :ingredient
И в Ingredient.rb
:
class Ingredient < ActiveRecord::Base
attr_accessible :name
validates :name, :uniqueness => { :case_sensitive => false }
has_many :quantities
has_many :recipes, through: :quantities
Вот моя вложенная форма, которая отображается на Recipe#new
:
<%= form_for @recipe do |f| %>
<%= render 'recipe_form_errors' %>
<%= f.label :name %><br>
<%= f.text_field :name %><br>
<h3>Ingredients</h3>
<div id='ingredients'>
<%= f.fields_for :quantities do |ff| %>
<div class='ingredient_fields'>
<%= ff.fields_for :ingredient_attributes do |fff| %>
<%= fff.label :name %>
<%= fff.text_field :name %>
<% end %>
<%= ff.label :amount %>
<%= ff.text_field :amount, size: "10" %>
<%= ff.hidden_field :_destroy %>
<%= link_to_function "remove", "remove_fields(this)" %><br>
</div>
<% end %>
<%= link_to 'Add ingredient', "new_ingredient_button", id: 'new_ingredient' %>
</div><br>
<%= f.label :description %><br>
<%= f.text_area :description, rows: 4, columns: 100 %><br>
<%= f.label :directions %><br>
<%= f.text_area :directions, rows: 4, columns: 100 %><br>
<%= f.submit %>
<% end %>
link_to
и link_to_function
там, чтобы разрешить добавление и удаление пар количество/ингредиента на лету, и были адаптированы из Railscast упоминалось ранее. Они могут использовать некоторые рефакторинги, но работают более или менее так, как должны.
Обновление: запрос Per Леже, здесь соответствующий код из recipes_controller.rb
. В маршруте Recipes#new
3.times { @recipe.quantities.build }
устанавливает три пустые пары количества/ингредиентов для любого данного рецепта; их можно удалить или добавить на лету, используя ссылки «Добавить ингредиент» и «удалить», упомянутые выше.
class RecipesController < ApplicationController
def new
@recipe = Recipe.new
3.times { @recipe.quantities.build }
@quantity = Quantity.new
end
def create
@recipe = Recipe.new(params[:recipe])
if @recipe.save
redirect_to @recipe
else
render :action => 'new'
end
end
Спасибо за ответ. Я добавил соответствующий код контроллера в конец моего исходного сообщения. Нужно отметить, что в отношении логики в представлении, но я не уверен, какие строки являются оскорбительными. Я хотел убедиться, что пользователь может добавлять ингредиенты и их количества при создании рецепта, и я пытался ограничить код только тем, что требовалось для формы. –
Как заполнить поля ингредиентов при обновлении рецепта? Фрагмент сверху не работает. (Rails 4.1.4) – Scotty
Также, как я запрашиваю количество? Есть ли способ сопоставить его с ингредиентом? т. е. @ recipe.ingredient [1] .Чтобы? – Scotty