Godzilla74 Godzilla74 - 7 months ago 7
Ruby Question

Rails undefined method but method exists

Maybe I've been staring at this code for too long, but what I'm doing seems trivial, yet my code still isn't working.

I'm using a modal to submit parameters to a controller, which should PATCH the Object, but instead, I'm getting

undefined method 'ignore_reason=' for nil:NilClass
.

the modal



<div class="modal fade" id="deferHostModal" tabindex="-1" role="dialog" aria-labelledby="deferHostLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="deferHostLabel">Defer a Host</h4>
</div>
<div class="modal-body">
<p>Defering a host means that you're choosing to ignore the security risks that Neo has identified for the given host.
This host will be ignored from future security score calculations. By filling in the information below, you will defer risk for the host for 30 days.</p>
<br/>
<%= form_for @network_host, url: {controller: "network_hosts", action: "defer_host"} do |f| %>
<%= f.hidden_field :id, class: "form-control", required: "required" %>
<%= f.label :ignore_reason, "Defer Reason" %>
<%= f.text_area :ignore_reason, class: "form-control", required: "required" %>
<br/>
<%= f.label :ignore_name, "Your Name" %>
<%= f.text_field :ignore_name, class: "form-control", required: "required" %>

</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<%= f.submit "Save changes", class: "btn btn-primary btn-success" %>
</div>
<% end %>
</div>
</div>
</div>





Which submits to the
controllers/network_hosts
method
defer_host
:




def defer_host
@network_host = NetworkHost.where(id: params[:id]).first
@network_host.ignore_reason = params[:ignore_reason]
@network_host.ignore_name = params[:ignore_name]
@network_host.ignore_flag = true
@network_host.ignore_date = 30.days.from_now
@network_host.save

redirect_to root_path
end





I've restarted my Rails server after the latest migration which added the
ignore_reason
,
ignore_name
,
ignore_date
,
ignore_flag
.

A sample Rails Console output of a
NetworkHost
to confirm that the fields are there to write to:



#<NetworkHost id: 76, location_id: 14, mac_address: "D0:63:B4:00:5B:40", ip_address: "10.10.10.106", hostname: "OpenELEC", created_at: "2016-02-19 01:03:24", updated_at: "2016-04-14 19:30:21", deleted_at: nil, os_vendor: "Unknown", nickname: nil, vendor: "Unknown", os: "Unknown", ignore_reason: nil, ignore_name: nil, ignore_date: nil, ignore_flag: nil>





Also, to confirm that the parameters are being passed, on the Rails Error page (which shows the undefined method error), the parameters are at the bottom:



Parameters:

{"utf8"=>"✓",
"_method"=>"patch",
"authenticity_token"=>"a7kB1fDirzJFtRR2hBVt/64Z02ufxMzTfpZgKJoWSFI=",
"network_host"=>{"id"=>"76",
"ignore_reason"=>"test defer",
"ignore_name"=>"JF"},
"commit"=>"Save changes"}





Any help is greatly appreciated!

Answer

It seems like your @network_host in controller is nil cause id key nested in network_host (according to your params).

params[:id]
#=> nil
NetworkHost.where(id: params[:id]).first
#=> nil
params[:network_host][:id]
#=> "76"

Try:

@network_host = NetworkHost.where(id: params[:network_host][:id]).first
#=> #<NetworkHost id: 76, location_id: 14, mac_address: "D0:63:B4:00:5B:40", ....>
Comments