2014-09-17 2 views
1

Я разрабатываю форму, которая связывает рецепты, recipe_entries (has_many_though join table) и ингредиенты с автозаполнением jQuery в Rails 4. Я использую комбинацию simple_form, кокон и рельсы4-автозаполненные драгоценные камни. Идея состоит в том, что пользователи могут создавать рецепт и динамически добавлять и редактировать связанные ингредиенты с помощью автозаполнения (количество каждого ингредиента хранится в таблице соединений).Rails 4 - установить отображаемое значение при редактировании autocomplete inested fields_for

У меня есть большая функциональность, однако единственная проблема, которая все еще меня беспокоит, заключается в том, что мне пришлось создать компонент f.input для: ингредиент, который при редактировании рецепта показывает значения, такие как изображение ниже, а не желаемое имя связанный ингредиент.

enter image description here

Кроме того, я могу динамически создавать, удалять и обновлять все ингридиент ассоциации. Любые советы очень ценятся. Вот мой код:

Gemfile

gem 'rails', '4.0.2' 
gem 'jquery-rails' 
gem 'jquery-ui-rails' 
gem 'simple_form' 
gem "cocoon" 
gem 'rails4-autocomplete' 

Recipe.rb

class Recipe < ActiveRecord::Base 
    has_many :recipe_entries, :dependent => :destroy 
    has_many :ingredients, through: :recipe_entries 

    accepts_nested_attributes_for :recipe_entries,:allow_destroy => true 
    accepts_nested_attributes_for :ingredients 
end 

RecipeEntry.rb

class RecipeEntry < ActiveRecord::Base 
    belongs_to :recipe 
    belongs_to :ingredient 
end 

Ingredient.rb

class Ingredient < ActiveRecord::Base 
    has_many :recipe_entries 
    has_many :recipes, through: :recipe_entries 
end 

Рецепты Форма:

<%= simple_form_for(@recipe) do |f| %> 
    <% if @recipe.errors.any? %> 
    <div id="error_explanation"> 
     <h2><%= pluralize(@recipe.errors.count, "error") %> prohibited this recipe from being saved:</h2> 
     <ul> 
     <% @recipe.errors.full_messages.each do |msg| %> 
     <li><%= msg %></li> 
     <% end %> 
     </ul> 
    </div> 
    <% end %> 
    <%= f.input :name %> 
    <%= f.input :description %> 
    <div id="recipe_entries"> 
     <%= f.simple_fields_for :recipe_entries, :input_html => { :class => "form_inline" } do |entry|%> 
      <% render 'recipe_entry_fields', :f => entry %>  
     <% end %> 
     <%= link_to_add_association 'add recipe entry', f, :recipe_entries%> 
    </div> 
    <%= f.button :submit %> 
<% end %> 

recipe_entry_partial

<div class="nested-fields"> 

    <% @it=f.options[:child_index] %> 
    <%= f.input :ingredient_id, as: :hidden, input_html: {id: "ingredient_id#{@it}"} %> 
    <%= f.input :ingredient, :url => autocomplete_ingredient_name_recipes_path, :as => :autocomplete, :input_html => {id_element: "#ingredient_id#{@it}"}, placeholder: "Enter ingredient..." %> 
    <%= f.input :quantity %> 

    <%= link_to_remove_association "remove entry form", f %> 
</div> 

Update Я считаю, что самый простой способ решения проблемы редактирования отображения является предварительно вставить правильное значение в f.input, содержащий автозаполнения. например

<%= f.input :ingredient, :url => autocomplete_ingredient_name_recipes_path, :as => :autocomplete, :input_html => {id_element: "#ingredient_id#{@it}", value: f.object.ingredient.name}, placeholder: "Enter ingredient..." %> 

Несчастливо, это работает только с ассоциацией записей рецептов. Это означает, что я все еще могу получить значения, например. f.object.ingredient_id, который возвращает правильный результат. Однако я больше не могу получить связанный ингредиент. Кажется, я могу получить связанный ингредиент, но когда я пытаюсь, например, вызовите метод .name, я получаю ошибку nil.

Странно, я могу получить component_id, вызвав f.object.ingredient_id и могу получить Ингредиент из Модели, вызвав, например. Ingredient.get (1) .name. НО, я не могу динамически связывать два значения. Ingredient.get (f.object.ingredient_id) возвращает нулевую ошибку. Также с вызовами to_string или to_integer.

ответ

1

OK, решение полной автозаполнения в вложенном виде выглядит следующим образом:

<div class="nested-fields"> 
    <% @it=f.options[:child_index] %> 
    <%= f.input :ingredient_id, as: :hidden, input_html: {id: "ingredient_id#{@it}"} %> 
     <%= f.simple_fields_for :ingredients, f.object.ingredient do |ii| %> 
      <%= ii.input :name, :url => autocomplete_ingredient_name_recipes_path, :as => :autocomplete, :input_html => {id_element: "#ingredient_id#{@it}"}, placeholder: "Enter ingredient..." %> 
     <% end %> 
    <%= f.input :quantity %> 

    <%= link_to_remove_association "remove entry form", f %> 
</div> 

Хитрость в том, чтобы поместить f.input автозаполнения внутри другого тега fields_for и убедитесь, чтобы задать контекст для каждого recipe_entry с f.object.ingredient. Помимо этого частичного, мне не пришлось вносить какие-либо изменения!

+0

Это сработало для меня с nested_form_fields, если кто-то еще споткнется об этой проблеме. – Maltiriel

Смежные вопросы