4

I cannot get a form to submit the desired parameters. I have a form which needs to accept a hidden_field for the model notice. This is the form in the view:

<%= form_for(:notice, url: :notices, method: :post, html: { multipart: true, class: "comment_form" } ) do |f| %>
  <%= hidden_field_tag :callsign, @character.callsign %>
  <%= f.fields_for :active_comment_relationship do |ff| %>
    <%= ff.hidden_field :commentee_id, value: notice.id %>
  <% end %>
  <%= f.hidden_field :latitude,  value: notice.latitude,  id: "comment_notice_latitude"  %>
  <%= f.hidden_field :longitude, value: notice.longitude, id: "comment_notice_longitude" %>
  <%= f.text_area :content, rows: 1, id: "commentField-#{notice.id}", class: "comment_area" %>
  <%= f.submit( "Post", class: 'btn btn-default btn-xs', 
                onclick: "return validateCommentForm('#commentField-#{notice.id}');" ) do %>
    <span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
  <% end %>
    <%= f.file_field :picture, accept: 'image/jpeg,image/gif,image/png' %>f
<% end %>

notices_controller.rb:

def notice_params
  params.require(:notice).permit( :content, :picture, :latitude, :longitude, active_comment_relationship_attributes: [:commentee_id] )
end

notice.rb:

has_one  :active_comment_relationship, class_name: "Commentrelationship",
                                     foreign_key: "commenter_id",
                                     dependent: :destroy
has_one  :supernotice, through: :active_comment_relationship, source: :commentee
accepts_nested_attributes_for :active_comment_relationship

The logs:

Started POST "/notices" for ::1 at 2015-08-03 12:12:35 +0100
Processing by NoticesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"ERlV0sDP7QWVimD1iErH7ICWMo7z5u7ASJBaFbotoL5HPZ5fo5eoZD38mKfSPDXXW1ew7ttBN/FPQoqQEfnbkQ==", "callsign"=>"bazzer", "notice"=>{"latitude"=>"51.80182150078305", "longitude"=>"-0.54107666015625", "content"=>"jhgf"}, "commit"=>"Drop"}
Character Load (0.6ms)  SELECT  "characters".* FROM "characters" WHERE "characters"."callsign" = $1 LIMIT 1  [["callsign", "bazzer"]]
User Load (2.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 1]]
CACHE (0.0ms)  SELECT  "characters".* FROM "characters" WHERE "characters"."callsign" = $1 LIMIT 1  [["callsign", "bazzer"]]
CACHE (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 1]]
(1.5ms)  BEGIN
SQL (29.1ms)  INSERT INTO "notices" ("content", "latitude", "longitude", "character_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id"  [["content", "jh"], ["latitude", 51.80182150078305], ["longitude", -0.54107666015625], ["character_id", 1], ["created_at", "2015-08-03 11:12:35.249337"], ["updated_at", "2015-08-03 11:12:35.249337"]]
(9.2ms)  COMMIT
--- !ruby/hash:ActionController::Parameters
utf8: ✓
authenticity_token: ERlV0sDP7QWVimD1iErH7ICWMo7z5u7ASJBaFbotoL5HPZ5fo5eoZD38mKfSPDXXW1ew7ttBN/FPQoqQEfnbkQ==
callsign: bazzer
notice: !ruby/hash:ActionController::Parameters
  latitude: '51.80182150078305'
  longitude: '-0.54107666015625'
  content: jhgf
commit: Drop
controller: notices
action: create
Completed 500 Internal Server Error in 87ms (ActiveRecord: 42.4ms)

NoMethodError (undefined method `[]' for nil:NilClass):
  app/controllers/notices_controller.rb:15:in `create'

Cannot render console with content type multipart/form-dataAllowed content types: [#<Mime::Type:0x000001052aae80 @synonyms=["application/xhtml+xml"], @symbol=:html, @string="text/html">, #<Mime::Type:0x000001052aab60 @synonyms=[], @symbol=:text, @string="text/plain">, #<Mime::Type:0x000001052b2ab8 @synonyms=[], @symbol=:url_encoded_form, @string="application/x-www-form-urlencoded">]

Why is the active_comment_relationship parameter not being submitted?

Bazley
  • 2,699
  • 5
  • 36
  • 61
  • its possible you didnt whitelist it in your rails strong params? – Ricky Mason Aug 03 '15 at 00:30
  • Do you have a nil object or some data missing ? – Grant Sayer Aug 03 '15 at 03:54
  • `NoMethodError (undefined method [] for nil:NilClass)` On which line? – Pavan Aug 03 '15 at 05:26
  • The NoMethodError is on this line: `if !params[:notice][:active_comment_relationship][:commentee_id].nil?` – Bazley Aug 03 '15 at 11:15
  • So, you don't want to include the whole log? Can you check for unpermitted parameters errors then (as Ricky mentioned)? When you troubleshoot a problem you see what you want to see, but others may want to see other things that you do not notice. –  Aug 03 '15 at 11:37
  • Consider refactoring `if !---.nil?` to `if ---`. That double negative is hard to follow. – fylooi Aug 03 '15 at 16:58

2 Answers2

0

Most likely you do not build this active_comment_relationship object. You did not provide your controller action or the models for this form, so it is difficult to tell. You can view source in html and see whether this hidden field is there. Or you can try to add the following line:

<% f.object.build_active_comment_relationship unless f.object.active_comment_relationship %>
<%= f.fields_for :active_comment_relationship do |ff| %>

It will build the active_comment_relationship in case it is missing.

Assuming that your notice has has_one active_comment_relationship association.

  • Sorry, I've added the controller and model code. Also, the field is present in the html: – Bazley Aug 03 '15 at 11:11
  • @Bazley, I missed the NoMethodError error that Pavan mentioned in his comment. Could you please add the whole log starting from the parameters hash? –  Aug 03 '15 at 11:15
  • @Bazley: Something does not match or missing. Your "Parameters:" hash is saying that your are using "commit"=>"Drop", but your form has f.submit( "Post"...). Maybe your validateCommentForm does something to params or you are looking on the wrong form. –  Aug 03 '15 at 12:01
  • @Bazley: also check your error here (http://stackoverflow.com/questions/29934438/rails-4-paperclip-4-2-1-give-error-with-binary-file-upload). It looks like the same ("Cannot render console with content type"). –  Aug 03 '15 at 12:04
0

Ok, I've got a solution. Simply changing

<%= form_for(:notice, url: :notices, method: :post, html: { multipart: true, class: "comment_form" } ) do |f| %>

to

<%= form_for(:notice, url: :notices, method: :post, multiple: true, html: { class: "comment_form" } ) do |f| %>

did the trick. The parameters now include active_comment_relationship:

authenticity_token: oqkA9bI2Jnt87CtSW0gNYdWJVzrmB63D/fsvoeskmNz0jct40W5jGtSa0wABPv9aDkjVWs6gdPL6Kf8kQPDj8w==
callsign: bazzer
notice: !ruby/hash:ActionController::Parameters
  active_comment_relationship: !ruby/hash:ActionController::Parameters
    commentee_id: '15071'
  latitude: '51.7559402747204'
  longitude: '-0.7470703125'
  content: jjj
commit: Post
controller: notices
action: create

(Note that multipart has changed to multiple, only because the docs hardly mention multipart, although both work).

On a related note, changing the above to an instance variable does not work (again the active_comment_relationship parameter is not submitted):

<%= form_for(@notice, url: :notices, method: :post, multiple: true, html: { class: "comment_form" } ) do |f| %> <!-- FAIL -->

Variations thereof also don't work:

<%= form_for(@notice, url: :notices, multiple: true) do |f| %> <!-- FAIL -->
<%= form_for(@notice, multiple: true) do |f| %> <!-- FAIL -->

I have no idea why the instance variable version doesn't work. If anyone has any idea why it would be great to hear from you!

Bazley
  • 2,699
  • 5
  • 36
  • 61