以嵌套形式通过 collection_select 提交时未保存
Id not saved when submitted through collection_select in nested form
我正在开发一个计算口粮的程序。每个口粮都有 ration_items,由饲料和数量组成。
class RationItem < ActiveRecord::Base
belongs_to :feedstuff
belongs_to :ration
validates :name, presence: true
def to_s
name
end
end
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
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
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
我希望用户能够在 ration/edit 视图中将 ration_items 添加到定量中。嵌套形式如下所示:
<%= 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 %>
然而,当使用 collection_select 时,此表单不保存 feedstuff_id 属性。 (它确实在通过 number_field 提交 id 时保存了 feedstuff_id 属性,因此可以设置强参数)。
提交新 ration_item 时的服务器操作是这样的:
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)
从外观上看,feedstuff_id 位于名为 ration_item 的数组中,而其他属性位于名为 ration_items_attributes?
我想我必须在 rations_controller 编辑操作中组织它,但我无法找出正确的方法。
任何帮助表示赞赏!
改变一下
<%= 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'}) %>
这样你会在ration_items_attributes
中得到feedstuff_id
并且你可以将feedstuff_id
保存到DB 无需更改任何控制器代码。
我正在开发一个计算口粮的程序。每个口粮都有 ration_items,由饲料和数量组成。
class RationItem < ActiveRecord::Base
belongs_to :feedstuff
belongs_to :ration
validates :name, presence: true
def to_s
name
end
end
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
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
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
我希望用户能够在 ration/edit 视图中将 ration_items 添加到定量中。嵌套形式如下所示:
<%= 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 %>
然而,当使用 collection_select 时,此表单不保存 feedstuff_id 属性。 (它确实在通过 number_field 提交 id 时保存了 feedstuff_id 属性,因此可以设置强参数)。 提交新 ration_item 时的服务器操作是这样的:
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)
从外观上看,feedstuff_id 位于名为 ration_item 的数组中,而其他属性位于名为 ration_items_attributes? 我想我必须在 rations_controller 编辑操作中组织它,但我无法找出正确的方法。 任何帮助表示赞赏!
改变一下
<%= 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'}) %>
这样你会在ration_items_attributes
中得到feedstuff_id
并且你可以将feedstuff_id
保存到DB 无需更改任何控制器代码。