Как создать элемент в глубоко вложенной форме в activeadmin/formtastic

Некоторое время я застрял на том, как создать глубоко вложенную форму с помощью formtastic в ActiveAdmin. Вот пример структуры моей модели:

class Herb < ActiveRecord::Base
has_one :medicinal
attr_accessible :medicinal_attributes
accepts_nested_attributes_for :medicinal

Трава имеет одно лекарственное средство (использование)

class Medicinal < ActiveRecord::Base
attr_accessible :recipe_attributes
belongs_to :herb
has_and_belongs_to_many :recipes
accepts_nested_attributes_for :recipes

Лекарственное средство (использование) может иметь много рецептов.

class Recipe < ActiveRecord::Base
has_and_belongs_to_many :medicinals
has_many :recipe_ingredients
has_many :ingredients, :through => :recipe_ingredients
attr_accessible :recipe_ingredients_attributes
accepts_nested_attributes_for :recipe_ingredients

И рецепт может иметь много ингредиентов (через recipe_ingredients)

class RecipeIngredient < ActiveRecord::Base
attr_accessible :ingredient_attributes
belongs_to :recipe
belongs_to :ingredient

Ингредиент

class Ingredient < ActiveRecord::Base
    attr_accessible :item
has_many :recipes, :through => :recipe_ingredients 

Итак, вот моя проблема. Я хочу, чтобы пользователь со страницы "Ввод травы" в ActiveAdmin мог создать рецепт, чтобы можно было автоматически вводить траву в качестве ингредиента, а если пользователь вводит ингредиент, который в данный момент не существует, введите его как НОВЫЙ ингредиент (чтобы другие рецепты могли его использовать). Я не думаю, что понимаю, как использовать контроллер в ActiveAdmin достаточно хорошо, чтобы знать, с чего начать... Вот что у меня так далеко:

ActiveAdmin.register Herb do

controller do
 def new
  @herb = Herb.new
  @herb.build_medicinal
 end
 def edit
  @herb = Herb.find(params[:id])
  if @herb.medicinal.blank?
    @herb.build_medicinal  
  end
 end
end

  form do |f|
   f.inputs "Herb" do
   f.inputs :name => "Medicinal", :for => :medicinal do |med| 
    med.input :content,  :label => "Medicinal Uses", :required => true
     med.has_many :recipes do |r|
      r.inputs "Recipe" do
       r.has_many :recipe_ingredients do |i|
        i.inputs "Ingredients" do
          i.input :ingredient
        end
       end
      end
     end
    end 
   end
  f.actions
  end

Я знаю, что это долго, но любой совет, который вы могли бы дать мне, был бы очень признателен. Я довольно плохо знаком с рельсами. Спасибо!

1 ответ

Решение

Если бы я создавал один и тот же сайт, я мог бы немного переместить структуру файлов, чтобы получить результат, который вы ищете.

приложение / администратор / herb.rb

ActiveAdmin.register Herb do
end

Это должно быть все, что вам нужно для создания страницы в active_admin. Тогда для вашего приложения / controller / herb_controller.rb

class HerbController < ApplicationController
 def new 
  @herb = Herb.new
 end 
end   

Я бы сейчас проверил, чтобы убедиться, что вы можете перейти к ActiveAdmin и создать новую траву. Кроме того, я бы добавил в ваш app / controller / herb_controller.rb, чтобы проверить, нужно ли добавлять новый ингредиент при создании травы.

...
def create
 @herb = Herb.new
 if @herb.save
  @herb.create_ingredient_if_not_existing
  # perform any other actions, such as flash message or redirect 
 else
  # perform action if save not successful
 end
end

Теперь вы хотите создать метод в своей модели Herb

def create_if_not_existing
 unless Ingredient.where("name = ?", self.name) then
  new_ingredient = ingredient.build
  new_ingredient.name = self.name
  # add extra attributes here if necessary
  new_ingredient.save
 end
end

Затем вы можете убедиться, что вы не создаете дубликаты ни в одной из ваших моделей с линией, подобной этой:

validates :name, :uniqueness => true

Это мой первый ответ о переполнении стека, поэтому дайте мне знать, если это вам чем-то поможет! Я боролся с такими же вещами не так давно, и мне повезло, что несколько человек помогли мне на этом пути.

Другие вопросы по тегам