Rails嵌套fields_for DB中的重复记录

时间:2014-08-20 20:03:20

标签: ruby-on-rails ruby-on-rails-4 nested-forms nested-attributes

  1. 问题是如何重构_form.html.erb以正确地将所有数据保存到数据库而不重复entrie。
  2. 问题是当尝试在估价行中创建新行时,将行保存在一行valu_id,part_id和另一行valu_id和pruchase_price中。一种重复的行,而它应该将所有这些数据合并在一行中。
  3. 情况是我有一个估值模型,它有很多valu_lines。该计划的目标是准备一个包含多个部分(项目上的项目)的评估(报价)。我正在使用连接表valu_lines,它存储了不同估值的每一行。 (为了简单起见,我的表格只有一个评估线)。

    PS。我在嵌套模型上进行了所有railscast ...... :(

    我的估价表格如下:

       <%= form_for(@valuation) do |f| %>
      <% if @valuation.errors.any? %>
        <div id="error_explanation">
          <h2><%= pluralize(@valuation.errors.count, "error") %> prohibited this valuation from being saved:</h2>
    
          <ul>
          <% @valuation.errors.full_messages.each do |msg| %>
            <li><%= msg %></li>
          <% end %>
    
          </ul>
        </div>
      <% end %>
    
      <div class="field">
        <%= f.label :description %><br>
        <%= f.text_area :description %>
      </div>
    <div class="field">
    
    </div>
    <div class="field">
    
    <%= f.fields_for :valuation_lines do |builder| %>
    
    <%= f.collection_select(:part_ids, @parts, :id, :name) %><br/>
          <%= builder.label :pruchase_price, "Price:" %> <br/>
          <%= builder.text_field :pruchase_price %>
    <% end %>
    
    </div>    
    
    <div class="field">
    <br>  
      <div class="actions">
        <%= f.submit %>
      </div>
    <% end %>
    

    valuations_controller.rb

    class ValuationsController < ApplicationController
      before_action :set_valuation, only: [:show, :edit, :update, :destroy]
    
      # GET /valuations
      # GET /valuations.json
      def index
        @valuations = Valuation.all
      end
    
      # GET /valuations/1
      # GET /valuations/1.json
      def show
      end
    
      # GET /valuations/new
      def new
        @valuation = Valuation.new
        @parts = Part.all
        @valuation.valuation_lines.build
      end
    
      # GET /valuations/1/edit
      def edit
      end
    
      # POST /valuations
      # POST /valuations.json
      def create
        @valuation = Valuation.new(valuation_params)
    
        respond_to do |format|
          if @valuation.save
            format.html { redirect_to @valuation, notice: 'Valuation was successfully created.' }
            format.json { render action: 'show', status: :created, location: @valuation }
          else
            format.html { render action: 'new' }
            format.json { render json: @valuation.errors, status: :unprocessable_entity }
          end
        end
      end
    
      # PATCH/PUT /valuations/1
      # PATCH/PUT /valuations/1.json
      def update
        respond_to do |format|
          if @valuation.update(valuation_params)
            format.html { redirect_to @valuation, notice: 'Valuation was successfully updated.' }
            format.json { head :no_content }
          else
            format.html { render action: 'edit' }
            format.json { render json: @valuation.errors, status: :unprocessable_entity }
          end
        end
      end
    
      # DELETE /valuations/1
      # DELETE /valuations/1.json
      def destroy
        @valuation.destroy
        respond_to do |format|
          format.html { redirect_to valuations_url }
          format.json { head :no_content }
        end
      end
    
      private
        # Use callbacks to share common setup or constraints between actions.
        def set_valuation
          @valuation = Valuation.find(params[:id])
        end
    
        # Never trust parameters from the scary internet, only allow the white list through.
        def valuation_params
           params.require(:valuation).permit(:description, :part_id, :valuation_id, :pruchase_price, :valuation_line, :quantity, :part_ids, parts_attributes: [:id, :code, :name], valuation_lines_attributes: [:id, :valuation_id, :part_id, :pruchase_price, :quantity])
    
      end
    end
    

    估价模型

     class Valuation < ActiveRecord::Base
            has_many :valuation_lines
            has_many :parts, :through => :valuation_lines
            accepts_nested_attributes_for :parts
            accepts_nested_attributes_for :valuation_lines
    
        end
    

    Valuation_line模型

    class ValuationLine < ActiveRecord::Base
        belongs_to :part
        belongs_to :valuation
    end
    

    零件模型

    class Part < ActiveRecord::Base
        has_many :valuation_lines
        has_many :valuations, :through => :valuation_lines
    end
    

    schema_db:

      create_table "parts", force: true do |t|
        t.string   "code"
        t.string   "name"
        t.datetime "created_at"
        t.datetime "updated_at"
      end
    
      create_table "valuation_lines", force: true do |t|
        t.integer "valuation_id"
        t.integer "part_id"
        t.integer "pruchase_price"
        t.integer "quantity"
      end
    
      create_table "valuations", force: true do |t|
        t.text     "description"
        t.datetime "created_at"
        t.datetime "updated_at"
      end
    
    end
    
    添加新的估值回报后

    开发日志:

    Started POST "/valuations" for 127.0.0.1 at 2014-08-20 22:08:46 +0200
    Processing by ValuationsController#create as HTML
      Parameters: {"utf8"=>"✓", 
    "authenticity_token"=>"6ADrGOl39bdD3FExQj0l405SXKgJ2zwCqVi6p+JQFw4=", "valuation"=>{"description"=>"33", "part_ids"=>"1"}, "valuation_lines"=>{"pruchase_price"=>"888"}, "commit"=>"Create Valuation"}
      [1m[36mPart Load (38.0ms)[0m  [1mSELECT "parts".* FROM "parts" WHERE "parts"."id" = ? LIMIT 1[0m  [["id", 1]]
      [1m[35m (0.0ms)[0m  begin transaction
      [1m[36mSQL (29.0ms)[0m  [1mINSERT INTO "valuations" ("created_at", "description", "updated_at") VALUES (?, ?, ?)[0m  [["created_at", Wed, 20 Aug 2014 20:08:46 UTC +00:00], ["description", "33"], ["updated_at", Wed, 20 Aug 2014 20:08:46 UTC +00:00]]
      [1m[35mSQL (0.0ms)[0m  INSERT INTO "valuation_lines" ("part_id", "valuation_id") VALUES (?, ?)  [["part_id", 1], ["valuation_id", 59]]
      [1m[36m (76.0ms)[0m  [1mcommit transaction[0m
    Redirected to http://localhost:3000/valuations/59
    Completed 302 Found in 262ms (ActiveRecord: 143.0ms)
    

2 个答案:

答案 0 :(得分:0)

我不确定这是问题,但不应该这一行:

 <%= fields_for :valuation_lines do |builder| %>

是这样的:

<%= f.fields_for :valuation_lines do |builder| %>

答案 1 :(得分:0)

终于明白了。为了避免重复的条目,只需要像这样重新安排_form.html.erb:

<div class="field">
    <%= f.label :description %><br>
    <%= f.text_area :description %>
  </div>

  <div class="field">

  <%= f.fields_for :valuation_lines do |builder| %>

      <%= builder.collection_select(:part_id, @parts, :id, :name) %><br/>
      <%= builder.label :pruchase_price, "Price:" %> <br/>
      <%= builder.text_field :pruchase_price %>

  <% end %>