问题
No idea whats going wrong here. From memory it used to work fine but I just recently used the form and realised it has stopped working somewhere in the process of building the app. Mini test still passes it which could mean it is something trivial or on the form directly.
I'm trying to get the nested attribute value
to pass on the from submit
category_item model
has_many :category_item_values, dependent: :destroy
accepts_nested_attributes_for :category_item_values
extend FriendlyId
friendly_id :name, use: :slugged
category_item_value model
belongs_to :category_item
category_items/edit.html.erb
<%= form_for([@category, @category_item], url: category_items_update_path) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.fields_for :category_item_values do |item_value| %>
<div class="value_fields">
<%= item_value.object.key %><br>
<%= item_value.label :value %>
<%= item_value.text_field :value %>
</div>
<% end %>
<%= f.submit "Save"%>
<% end %>
category_item controller
def edit
@guide = Guide.friendly.find(params[:guide_id])
@category = Category.friendly.find(params[:category_id])
@category_item = @category.category_items.friendly.find params[:id]
end
def update
@guide = Guide.friendly.find(params[:guide_id])
@category = Category.friendly.find(params[:category_id])
@category_item = @category.category_items.friendly.find params[:id]
if @category_item.update (item_params)
flash[:success] = "Updated. Thanks for contributing!"
redirect_to category_items_show_path(@guide, @category, @category_item)
else
render 'edit'
end
end
private
def item_params
params.require(:category_item).permit(:name, category_item_values_attributes: [:id, :value])
end
parpamters passed when the form is submitted
Parameters: {"utf8"=>"✓", "authenticity_token"=>"O/+jbpxxY9ACV1+M7SQoYXHGvhOlgT/SufGoFpjTKaxqewnQ0IKRJWF+kxoE99DCaiKYPVkKtctSrQ0hPegIEw==", "category_item"=>{"category_item_values_attributes"=>{"0"=>{"id"=>"39"}, "1"=>{"id"=>"40"}, "2"=>{"id"=>"41"}, "3"=>{"id"=>"42"}, "4"=>{"id"=>"43"}, "5"=>{"id"=>"44"}, "6"=>{"id"=>"45"}, "7"=>{"id"=>"46"}, "8"=>{"id"=>"47"}, "9"=>{"id"=>"48"}, "10"=>{"id"=>"49"}}}, "commit"=>"Save", "guide_id"=>"dungeon-boss", "category_id"=>"heroes", "id"=>"smok"}
The mini test that passes
test "mod editing all category items successfully" do
log_in_as(@user)
get category_items_edit_path(@guide, @category, @category_item)
assert_template 'category_items/edit'
assert_select 'form.edit_category_item'
assert CategoryItemValue.find(1).value == 'simmv' #confirm value before edit
patch category_items_update_path(params: {key_id: 1}), category_item: { category_item_values_attributes: [id: 1, value: "333"]}
assert CategoryItemValue.find(1).value == '333' #confirm value changed after edit
follow_redirect!
assert_template 'category_items/show'
assert_select 'div.alert'
end
Been over it a few times but cant figure out how to get the value
nested attribute to pass into the params and db from the form submit.
categroy_item_values schema
create_table "category_item_values", force: :cascade do |t|
t.string "key"
t.integer "key_type"
t.text "value"
t.integer "category_item_key_id"
t.integer "category_item_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
*Here is the log of loading the page then submitting the form
Started GET "/guides/dungeon-boss/heroes/rock/edit" for ::1 at 2016-02-16 21:59:16 +1100
Processing by CategoryItemsController#edit as HTML
Parameters: {"guide_id"=>"dungeon-boss", "category_id"=>"heroes", "id"=>"rock"}
[1m[35mUser Load (0.1ms)[0m SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
[1m[36mGuide Load (0.1ms)[0m [1mSELECT "guides".* FROM "guides" WHERE "guides"."slug" = ? ORDER BY "guides"."id" ASC LIMIT 1[0m [["slug", "dungeon-boss"]]
[1m[35mCategory Load (0.1ms)[0m SELECT "categories".* FROM "categories" WHERE "categories"."slug" = ? ORDER BY "categories"."id" ASC LIMIT 1 [["slug", "heroes"]]
[1m[36mGameModsRelationship Exists (0.1ms)[0m [1mSELECT 1 AS one FROM "game_mods_relationships" WHERE "game_mods_relationships"."user_id" = ? AND "game_mods_relationships"."category_id" = 7 LIMIT 1[0m [["user_id", 1]]
[1m[35mCategoryItem Load (0.2ms)[0m SELECT "category_items".* FROM "category_items" WHERE "category_items"."category_id" = ? AND "category_items"."slug" = ? ORDER BY "category_items"."id" ASC LIMIT 1 [["category_id", 3], ["slug", "rock"]]
[1m[36mCACHE (0.0ms)[0m [1mSELECT 1 AS one FROM "game_mods_relationships" WHERE "game_mods_relationships"."user_id" = ? AND "game_mods_relationships"."category_id" = 7 LIMIT 1[0m [["user_id", 1]]
Rendered shared/_error_messages.html.erb (0.1ms)
[1m[35mCategoryItemValue Load (0.2ms)[0m SELECT "category_item_values".* FROM "category_item_values" WHERE "category_item_values"."category_item_id" = ? [["category_item_id", 10]]
Rendered category_items/edit.html.erb within layouts/application (19.5ms)
Rendered layouts/_shim.html.erb (0.0ms)
Rendered layouts/_header.html.erb (0.5ms)
Rendered layouts/_footer.html.erb (0.2ms)
Completed 200 OK in 230ms (Views: 221.2ms | ActiveRecord: 0.8ms)
Started PATCH "/guides/dungeon-boss/heroes/rock" for ::1 at 2016-02-16 21:59:21 +1100
Processing by CategoryItemsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"fT4HylfaCf9ONVlRYLKP9jP4nlerxMZoyyYJkx0mDkwsuq10Gyn7Ci0clceJYXdVKBy4eVdPTHEgeqykuB0v8w==", "category_item"=>{"category_item_values_attributes"=>{"0"=>{"id"=>"28"}, "1"=>{"id"=>"29"}, "2"=>{"id"=>"30"}, "3"=>{"id"=>"31"}, "4"=>{"id"=>"32"}, "5"=>{"id"=>"33"}, "6"=>{"id"=>"34"}, "7"=>{"id"=>"35"}, "8"=>{"id"=>"36"}, "9"=>{"id"=>"37"}, "10"=>{"id"=>"38"}, "11"=>{"id"=>"39"}, "12"=>{"id"=>"40"}, "13"=>{"id"=>"41"}, "14"=>{"id"=>"42"}, "15"=>{"id"=>"43"}, "16"=>{"id"=>"44"}, "17"=>{"id"=>"45"}, "18"=>{"id"=>"46"}, "19"=>{"id"=>"47"}, "20"=>{"id"=>"48"}, "21"=>{"id"=>"49"}, "22"=>{"id"=>"50"}, "23"=>{"id"=>"51"}, "24"=>{"id"=>"52"}, "25"=>{"id"=>"53"}, "26"=>{"id"=>"54"}, "27"=>{"id"=>"55"}, "28"=>{"id"=>"56"}, "29"=>{"id"=>"57"}}}, "commit"=>"Save", "guide_id"=>"dungeon-boss", "category_id"=>"heroes", "id"=>"rock"}
[1m[36mUser Load (0.1ms)[0m [1mSELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1[0m [["id", 1]]
[1m[35mGuide Load (0.1ms)[0m SELECT "guides".* FROM "guides" WHERE "guides"."slug" = ? ORDER BY "guides"."id" ASC LIMIT 1 [["slug", "dungeon-boss"]]
[1m[36mGameModsRelationship Exists (0.1ms)[0m [1mSELECT 1 AS one FROM "game_mods_relationships" WHERE "game_mods_relationships"."user_id" = ? AND "game_mods_relationships"."category_id" = 7 LIMIT 1[0m [["user_id", 1]]
[1m[35mCategory Load (0.1ms)[0m SELECT "categories".* FROM "categories" WHERE "categories"."slug" = ? ORDER BY "categories"."id" ASC LIMIT 1 [["slug", "heroes"]]
[1m[36mCategoryItem Load (0.1ms)[0m [1mSELECT "category_items".* FROM "category_items" WHERE "category_items"."category_id" = ? AND "category_items"."slug" = ? ORDER BY "category_items"."id" ASC LIMIT 1[0m [["category_id", 3], ["slug", "rock"]]
[1m[35mCACHE (0.0ms)[0m SELECT 1 AS one FROM "game_mods_relationships" WHERE "game_mods_relationships"."user_id" = ? AND "game_mods_relationships"."category_id" = 7 LIMIT 1 [["user_id", 1]]
[1m[36m (0.0ms)[0m [1mbegin transaction[0m
[1m[35mCategoryItemValue Load (0.3ms)[0m SELECT "category_item_values".* FROM "category_item_values" WHERE "category_item_values"."category_item_id" = ? AND "category_item_values"."id" IN (28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57) [["category_item_id", 10]]
[1m[36mCategoryItem Exists (0.1ms)[0m [1mSELECT 1 AS one FROM "category_items" WHERE (LOWER("category_items"."name") = LOWER('rock') AND "category_items"."id" != 10 AND "category_items"."guide_id" = 7) LIMIT 1[0m
[1m[35m (0.0ms)[0m commit transaction
Redirected to http://localhost:3000/guides/dungeon-boss/heroes/rock
Completed 302 Found in 16ms (ActiveRecord: 0.8ms)
Everything seems to work fine. Also when I manually give value
a value in the db it shows up in the forms input to be edited, so the form seems to be working correctly. Its just when I hit submit it wont add value
into the attributed parameters hash.
There is a bit going on in the log so if something confuses that you think might cause the problem just ask (I have a bad habit of assuming people know about parts of a random add they cant see).
回答1:
<%= form_for [@category, @category_item], url: category_items_update_path do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.fields_for :category_item_values do |item_value| %>
<%= item_value.object.key %>
<%= item_value.label :value %>
<%= item_value.text_field :value %>
<% end %>
<%= f.submit "Save"%>
<% end %>
Whenever you create code, you need to ensure it's indented properly.
This code is good; the likely issue is that you're using outdated code from some other view / action. If you posted your entire console log for the request, we could give you a more appropriate answer.
"guide_id"=>"dungeon-boss", "category_id"=>"heroes", "id"=>"smok"
This is from your params. This does not look like category_items_update_path
; perhaps it will help you identify the view that's being used.
回答2:
After searching high and low for a few days I managed to find the culprit was a bit of coffee script coding in a .coffee file. This coffescript was using jquery to change the way the forms html was ordered on the page making the part of the form html all jumbled. The coffeescript wasnt necessary (I was just playing around with jquery and forgot to get rid the coding a while back) so I removed it and voila, problem solved.
来源:https://stackoverflow.com/questions/35400048/rails-nested-forms-only-passing-the-id-on-form-submit