Correct way to access nested parameters

53 views
Skip to first unread message

Bazley

unread,
Aug 2, 2015, 4:15:18 PM8/2/15
to Ruby on Rails: Talk
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

_notice.html.erb:

    <%= form_tag( {controller: "notices", action: "create"}, method: "post", class: "comment_form", multipart: true ) do %>
     
<%= hidden_field_tag :callsign, @character.callsign %>
     
<%= hidden_field_tag "notice[active_comment_relationship][commentee_id]", notice.id %>
      .
      .

notices_controller.rb:

    @notice = @character.notices.build(notice_params)
   
if @notice.save
     
if !params[:notice][:active_comment_relationship][:commentee_id].nil? # THE OFFENDING LINE
       
@notice.create_comment(params[:notice][:active_comment_relationship][:commentee_id])
     
end
   
end

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


The code above gives the following error:

undefined method `[]' for nil:NilClass


Sometimes a notice is submitted with a blank/nil :commentee_id, so I would have thought !params[:notice][:active_comment_relationship][:commentee_id].nil?
would have worked. How do I write this correctly? How do you correctly access nested parameters?

Colin Law

unread,
Aug 2, 2015, 5:03:18 PM8/2/15
to Ruby on Rails: Talk
Are you sure it is not active_comment_relationship that is nil? Have
a look in the log and see what it says for params. If you think it is
ok copy/paste the log for the complete transaction here.

Colin

Elizabeth McGurty

unread,
Aug 2, 2015, 5:40:54 PM8/2/15
to Ruby on Rails: Talk
@Colin is right.  I think here that you should be asking, how can I learn the params returned?

To debug, modify.  That is what I have used, others may have better suggestions:

  if @notice.save
      puts params.to_yaml
     
if !params[:notice][:active_comment_relationship][:commentee_id].nil? # THE OFFENDING LINE

       
@notice.create_comment(params[:notice][:active_comment_relationship][:commentee_id])
     
end
   
end


puts params.to_yaml will return the structure and values to your logging.

Otherwise, you are testing too generally for uncertain aspects:
if !params[:notice][:active_comment_relationship][:commentee_id].nil?  

Test each aspect for the moment to ascertain missing values:

unless params[:notice].blank?
....
unless
params[:notice][:active_comment_relationship].blank?
....

unless
params[:notice][:active_comment_relationship][:commentee_id].blank?
...



Bazley

unread,
Aug 2, 2015, 7:15:48 PM8/2/15
to Ruby on Rails: Talk
You were right, it looks like it's active_comment_relationship is nil, I think. I added the yaml line and got this:

--- !ruby/hash:ActionController::Parameters

utf8: ✓

authenticity_token: nNWNdGOzKSu5gfDkB4x3AFIO1PQnIggn65uE//SGQNzK8Ub5AOtsShH3CLZd+oU7ic9WlA+F0RbsSVR6X1I78w==

callsign: bazzer

notice: !ruby/hash:ActionController::Parameters

  latitude: '51.75253980933651'

  longitude: '-1.39801025390625'

  content: Hello everyone

commit: Drop

controller: notices

action: create

Completed 500 Internal Server Error in 31ms (ActiveRecord: 7.1ms)

NoMethodError (undefined method `[]' for nil:NilClass):


I have updated my code to use a form builder. It's all working great except for this one problem. The code is below. For some reason the fields_for is not working - as the params above shows there should be an active_comment_relationship parameter for notice but it isn't present. What's wrong with this code?:


    <%= 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.label :commentee_id %>
       
<%= 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' %>
   
<% end %>





Elizabeth McGurty

unread,
Aug 2, 2015, 8:03:07 PM8/2/15
to Ruby on Rails: Talk
fields_for is a devil to understand, with and without a parent/data form.  You need to really study the Rails documentation a lot, create scenarios from your data....  Before you try fields_for you should test at 'rails console' for certainty that your associations are productive.   Be certain of your data before testing because association testing in true null/empty is pretty nondescript... If you are bold, go to GitHub, and search to Rails applications and then fields_for....

Best to you.

Liz

PS: Write to Colin Law, he is a wealth of information regarding tutorials...
Reply all
Reply to author
Forward
0 new messages