Как создать элемент в глубоко вложенной форме в 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
Это мой первый ответ о переполнении стека, поэтому дайте мне знать, если это вам чем-то поможет! Я боролся с такими же вещами не так давно, и мне повезло, что несколько человек помогли мне на этом пути.