以嵌套形式

时间:2015-07-25 09:59:33

标签: ruby-on-rails-4 nested-forms collection-select

我正在研究一个计算口粮的计划。每种口粮都有ration_items,由饲料和数量组成。



class RationItem < ActiveRecord::Base
  belongs_to :feedstuff
  belongs_to :ration
  validates :name, presence: true
  
  def to_s
    name
  end
end
&#13;
&#13;
&#13;

&#13;
&#13;
class Feedstuff < ActiveRecord::Base
  validates :user_id, presence: true
  validates :name, presence: true, length: {maximum: 20}, uniqueness: true
  belongs_to :user
  has_many :ration_items
  
  def to_s
    name
  end

    
end
&#13;
&#13;
&#13;

&#13;
&#13;
class Ration < ActiveRecord::Base
  belongs_to :user
  has_many :ration_items, dependent: :destroy
  accepts_nested_attributes_for :ration_items
  validates :name, presence: true
  validates :user_id, presence: true
  
  def to_s
    name
  end
  
end
&#13;
&#13;
&#13;

&#13;
&#13;
class RationsController < ApplicationController
  before_action :set_ration, only: [:show, :edit, :update, :destroy]

  # GET /rations
  # GET /rations.json
  def index
    @rations = Ration.all
  end

  # GET /rations/1
  # GET /rations/1.json
  def show  
  end

  # GET /rations/new
  def new
    @ration = Ration.new
  end

  # GET /rations/1/edit
  def edit
  end

  # POST /rations
  # POST /rations.json
  def create
    
    @ration = current_user.rations.build(ration_params)
    
    respond_to do |format|
      if @ration.save
        format.html { redirect_to @ration, notice: 'Ration was successfully created.' }
        format.json { render :show, status: :created, location: @ration }
      else
        format.html { render :new }
        format.json { render json: @ration.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /rations/1
  # PATCH/PUT /rations/1.json
  def update
    respond_to do |format|
      if @ration.update(ration_params)
        format.html { redirect_to @ration, notice: 'Ration was successfully updated.' }
        format.json { render :show, status: :ok, location: @ration }
      else
        format.html { render :edit }
        format.json { render json: @ration.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /rations/1
  # DELETE /rations/1.json
  def destroy
    @ration.destroy
    respond_to do |format|
      format.html { redirect_to rations_url, notice: 'Ration was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_ration
      @ration = Ration.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def ration_params
      params.require(:ration).permit(:name, :user_id, ration_items_attributes: [ :id, :quantity, :name, :feedstuff_id ])
    end
end
&#13;
&#13;
&#13;

我希望用户能够在配给/编辑视图中将配额添加到配给。嵌套表单如下所示:

&#13;
&#13;
<%= f.fields_for :ration_items, RationItem.new do |r| %>
    <%= r.label :quantity %>
    <%= r.number_field :quantity %><br>
    <%= r.label :name %>
    <%= r.text_field :name %><br>
    <%= r.label :feedstuff_id %>
    <%= collection_select(:ration_item, :feedstuff_id, Feedstuff.all, :id, :name, {prompt: 'Select Feedstuff'}) %>
  <% end %>
&#13;
&#13;
&#13;

但是,在使用collection_select时,此表单不会保存feedstuff_id属性。 (通过number_field提交id时,它确实保存了feedstuff_id属性,因此设置了强大的params)。 提交新的ration_item时的服务器操作如下:

&#13;
&#13;
Started PATCH "/rations/3" for 127.0.0.1 at 2015-07-25 11:30:01 +0200
Processing by RationsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"iH9Of4FEblYMcFz7Wu0dVp3yoIm58z30XrWX067PVNPc4N3FAFOg4yIUetz/7viuCCJf7a3REb7ief/qiM1dIQ==", "ration"=>{"name"=>"kalfjes", "ration_items_attributes"=>{"0"=>{"quantity"=>"100", "name"=>"krachtvoer"}}}, "ration_item"=>{"feedstuff_id"=>"15"}, "commit"=>"Ration bewaren", "id"=>"3"}
  Ration Load (0.1ms)  SELECT  "rations".* FROM "rations" WHERE "rations"."id" = ? LIMIT 1  [["id", 3]]
   (0.1ms)  begin transaction
  SQL (0.5ms)  INSERT INTO "ration_items" ("quantity", "name", "ration_id", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?)  [["quantity", 100.0], ["name", "krachtvoer"], ["ration_id", 3], ["created_at", "2015-07-25 09:30:01.236937"], ["updated_at", "2015-07-25 09:30:01.236937"]]
   (210.8ms)  commit transaction
Redirected to http://localhost:3000/rations/3
Completed 302 Found in 226ms (ActiveRecord: 211.5ms)
&#13;
&#13;
&#13;

从它的外观来看,feedstuff_id在一个名为ration_item的数组中,而其他属性在一个名为ration_items_attributes的数组中? 我认为我必须在rations_controller编辑操作中组织这个,但我可能无法弄清楚正确的方法。 任何帮助表示赞赏!

1 个答案:

答案 0 :(得分:0)

只需更改

<%= collection_select(:ration_item, :feedstuff_id, Feedstuff.all, :id, :name, {prompt: 'Select Feedstuff'}) %>

<%= r.collection_select(:feedstuff_id, Feedstuff.all, :id, :name, {prompt: 'Select Feedstuff'}) %>

这样您就可以feedstuff_id获得ration_items_attributes,并且可以将feedstuff_id保存到 数据库 ,而无需更改任何控制器代码。