Simpleform,一次创建两个嵌套模型

Simpleform, create two nested models at once

我有两个嵌套的模型,一个项目有一个名称和一个预算,一个预算有一个金额并且属于一个项目。

我有一个表单页面,我尝试在其中创建项目和预算,因此用户可以在他们选择预算金额的同一表单中填写他们的项目名称。

<%= simple_form_for @project do |f| %>
    <%= f.error_notification %>
    <%= simple_fields_for :budget do |ff| %>
      <%= ff.input :amount %>
    <% end %>
    <%= f.input :name %>
    <%= f.submit "Create", class: "btn" %>
  <% end %>

但是我不能同时创建两者,当我测试我的预算是否有效时,我错过了它链接到的 project_id,如果我尝试先创建我的项目,我不能导致它错过预算。

这是我的模型:

 class Budget < ApplicationRecord
   belongs_to :projects
 end
 class Project < ApplicationRecord
   has_one :budget
   accepts_nested_attributes_for :budget
 end

这是我的迁移

class CreateBudgets < ActiveRecord::Migration[5.1]
  def change
    create_table :budgets do |t|

      t.timestamps
    end
  end
end
class CreateProjects < ActiveRecord::Migration[5.1]
  def change
    create_table :projects do |t|
      t.references :budget, foreign_key: true
      t.string :name

      t.timestamps
    end
  end
end

最后是我的项目控制器 定义新 @project = Project.new @project.id = 0 @预算= Budget.new 放 "new in projectcontroler" 结束

def create
  puts "create in projectcontroler"
  # Getting filled objects from form
  @project = Project.new(project_params)
  @budget = Budget.new(budget_params)
  puts "We're on project controller"
  p @budget

  respond_to do |format|
    unless @budget.nil? 
      @project.budget = @budget

      if @project.valid?
        puts "All good now"
        @budget.save
        @project.save
        puts "Campaign successfuly created"
        format.html { redirect_to projects_path, notice: 'Success' }
      else
        puts "Unable to create campaign"
        format.html { render :new, notice: 'Project went wrong' }
      end

     else # If budget isn't saved
      puts "Unable to create budget"
      @budget.errors.full_messages.each do |mes|
        puts mes
      end
      format.html { render :new }
      format.json { render json: @budget.errors, status: :unprocessable_entity }
    end
  end
end

现在我遇到了这个问题:ActiveModel::MissingAttributeError - 无法写入未知属性 project_id

我需要了解是否需要为预算模型提供控制器或路由,我不能在同一个控制器中创建两个模型吗?

编辑:更新代码

编辑 2:我添加了迁移,因为我认为这是问题的一部分

class CreateProjects < ActiveRecord::Migration[5.1]
  def change
    create_table :projects do |t|
      t.references :budget, foreign_key: true
      t.string :name
      t.timestamps
    end
  end
end
class CreateBudgets < ActiveRecord::Migration[5.1]
  def change
    create_table :budgets do |t|
      t.string :amount
      t.timestamps
    end
  end
end

这里需要使用accepts_nested_attributes_for。它允许您通过父级保存关联记录的属性。

class Project < ApplicationRecord
   has_one :budget
   accepts_nested_attributes_for :budget
end

在这种情况下,您需要一个标准路线和一个项目表格:<%= simple_form_for @project do |f| %>

在 params 中,您将在 project_params 中得到一个散列 budget_attributes: {},因此您无需单独创建预算。

并且您需要更改迁移。如果你的Budget真的belongs_to到Project,那么budgetstable需要存储project_id,反之亦然。

控制器

def new
  @project = Project.new
end

def create
  @project = Project.new(project_params)


  respond_to do |format|
    if @project.save
      format.html { redirect_to projects_path, notice: 'Success' }
    else
      format.html { render :new, notice: 'Project went wrong' }
    end
  end
end

private
def project_params
  params.require(:project).permit(budget_attributes: [:id, :name])
end

您可以阅读更多相关内容here