【问题标题】:Simpleform, create two nested models at onceSimpleform,一次创建两个嵌套模型
【发布时间】:2018-01-29 10:22:12
【问题描述】:

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

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

<%= 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 将“新项目控制器” 结束

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 - can't write unknown attribute 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

【问题讨论】:

    标签: ruby-on-rails ruby activerecord rails-activerecord simple-form


    【解决方案1】:

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

    class Project < ApplicationRecord
       has_one :budget
       accepts_nested_attributes_for :budget
    end
    

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

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

    而且您需要更改迁移。如果您的 Budget 确实属于 Project,则 budgets 表需要存储 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

    【讨论】:

    • 谢谢!不幸的是,即使该行仍然出现“缺少属性错误”,我想我仍然有关于外键或类似内容的错误
    • 如果我用 belings_to 替换 has_one,它就可以工作。要使用 has_one,我需要在预算模型中手动添加 project_id 列。我不明白为什么
    • @Neustrony,我已经更新了我的答案。您在模型或迁移中的关联错误。请检查一下。而且你不能在关联的两边都有belongs_to
    • 但是活动记录应该单独处理列?我记得当我使用引用和模型关联时,所有内容都是由活动记录自动添加的,为什么这里不能这样?
    • 即使使用accepts_nested_attributes_for 和正确的迁移,我的属性也没有嵌套在rails 中,我将project=>{...},budget=>{...} 分开
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-30
    相关资源
    最近更新 更多