代码之家  ›  专栏  ›  技术社区  ›  Neustrony

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

  •  1
  • Neustrony  · 技术社区  · 8 年前

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

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

    <%= 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\u 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
    

    最后这是我的项目控制员 def新建 @项目=项目。新 @项目。id=0 @预算=预算。新 在projectcontroler中添加“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-无法写入未知属性 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
    
    1 回复  |  直到 8 年前
        1
  •  2
  •   Vasilisa    8 年前

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

    class Project < ApplicationRecord
       has_one :budget
       accepts_nested_attributes_for :budget
    end
    

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

    在params中,您将得到一个哈希 budget_attributes: {} 在…内 project_params ,因此不需要单独创建预算。

    您需要更改迁移。如果您的预算确实属于该项目,则预算表需要存储Project\u 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

    推荐文章