rails 3 - Help Returning a nil - ruby-on-rails

Hello I have the following in my Create Controller:
def create
#requestable = find_requestable
if !#requestable.nil?
. ..
And then:
def find_requestable
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
end
end
nil
end
this works find when find_requestable sends back a paratemter, but if it doesn't it's not sending back a NIL which causes everything to error with:
NameError (uninitialized constant Undefined):
app/controllers/request_threads_controller.rb:133:in `find_requestable'
app/controllers/request_threads_controller.rb:131:in `each'
app/controllers/request_threads_controller.rb:131:in `find_requestable'
app/controllers/request_threads_controller.rb:52:in `create'
app/middleware/flash_session_cookie_middleware.rb:14:in `call'
Why isn't find_requestable sending back nil? thank you

Third line of your find_requestable method, first check to see if name is blank. Give that a shot.
if !name.blank? && name =~ /(.+)_id$/
UPDATE: Answer in Comment:
The only other thing I can think of is that one of your params has Undefined as its value, which is causing return $1.classify.constantize.find(value) to throw up. Can you take a look at the HTTP Headers and the POST parameters that are being sent across the wire?

Related

NoMethodError (undefined method `each' for nil:NilClass):

class Api::SurveyAnswersController < ApplicationController
def create
# #survey_answer = SurveyAnswer.new(survey_answer_params)
survey_answers = []
survey_id = params[:survey_id]
params[:questions].each do |q|
answer = {survey_id: survey_id, option_ids: [], question_id: q[:id],
title: q[:answer]}
if q[:options].present?
selected_options = q[:answer].split(',')
selected_options.each do |selected_option|
q[:options].each do |option|
if option[:title]== selected_option
answer[:option_ids] << option[:id]
#<todo add break when in this condition
end
end
end
survey_answers << answer
end
end
puts survey_answers
# #survey_answers = SurveyAnswer.create(survey_answers)
if SurveyAnswer.create(survey_answers)
render json: survey_answers
end
end
end
I have a survey model which has some questions. Each question contains answers. When I try to hit post request through postman to insert answers, it gives 505 internal server error with message "undefined method each for nil:nilclass". Can anybody tell what the problem is?
You are trying to run the .each loop an empty object.
Make sure that both
params[:questions]
and
q[:options]
are not empty (not equal to nil).
NoMethodError sometimes sounds very unrepresentative, especially if you're just starting off with Ruby.
Try to browse Stackoverflow next time, because this has been answered here.

Stubbing Github module for test

In my gem i am using Github gem for GitHub API. I created a EachValidator for checking existency of some URL given:
def validate_each(record, attribute, value)
return if value.empty? and not opts[:presence]
if check_github_url value
repo_data = GithubStats::Parser.parse value
begin
Github.repos(user: repo_data[:username], repo: repo_data[:repo]).commits.all
rescue Github::Error::NotFound => e
p e
record.errors[attribute] << error_message
end
else
record.errors[attribute] << error_message
end
end
How to stub Github.repos method to return concrete values? Does change class for some stubbed (responding as I want) will be enough? I was using Mocha but i can't figure it out how to use here.
Edit:
I am considering:
# inside test class
def initialize
Github.stubs(:repos).returns(what_i_want_to_put_here)
end
First thing is to return good response or raise exception in condition of given params so i need to catch parameters somehow. Or maybe should I raise an exception of test case need it? That would be perfect and simple solution but gives me nothing from testing, am I right?
Edit 2:
I tried something like that:
#test case class
def initialize param
Github.stubs(:repos).returns({})
Github.repos.stubs(:commits).returns({})
Github.repos.commits.stubs(:all).returns({})
super param
end
def test_method
Github.repos.commits.stubs(:all).throws(Github::Error::NotFound.new({}))
# do the real method
validated_record = validate_github_url("https://github.com/puradawid/github_stats_notexisting") do |model, attr_name|
model.errors.[].expects('<<').once
end
end
But it is throwing an exception:
ArgumentError: uncaught throw #<Github::Error::NotFound: : >
/home/dawid/.rvm/gems/ruby-2.1.5/gems/mocha-1.1.0/lib/mocha/thrower.rb:10:in `throw'
/home/dawid/.rvm/gems/ruby-2.1.5/gems/mocha-1.1.0/lib/mocha/thrower.rb:10:in `evaluate'
/home/dawid/.rvm/gems/ruby-2.1.5/gems/mocha-1.1.0/lib/mocha/return_values.rb:20:in `next'
/home/dawid/.rvm/gems/ruby-2.1.5/gems/mocha-1.1.0/lib/mocha/expectation.rb:569:in `invoke'
/home/dawid/.rvm/gems/ruby-2.1.5/gems/mocha-1.1.0/lib/mocha/mock.rb:296:in `method_missing'
/home/dawid/.rvm/gems/ruby-2.1.5/gems/mocha-1.1.0/lib/mocha/class_method.rb:63:in `all'
/home/dawid/github_stats/lib/validators/github_projects_url_validator.rb:8:in `validate_each'
/home/dawid/github_stats/test/github_validator_test.rb:85:in `validate_github_url'
/home/dawid/github_stats/test/github_validator_test.rb:45:in `block in <class:GithubStatsValidatorTest>'
Look at the first code here. It is catching Github::Error:NotFound so what is the problem with the code here?
Try
Github.expects(:repos).returns(JSON.generate("Some Return Value"))
So assuming you are expecting the API to return JSON you could do
require 'json'
...
Github.expects(:repos).returns(JSON.generate({some: :hash}))

Substitute commas with dots in a BigDecimal

I would like that if a user type "100,50" or "100.50" is the same thing. 100$ and 50 cents.
before_validation :strip_commas
def strip_commas
unless self.total_less_tax.blank?
self.total_less_tax = total_less_tax.tgsub(",", ".").to_f
end
end
but I get this error
NoMethodError (undefined method `gsub' for #<BigDecimal:7fc1ba371f08,'0.1E6',9(18)>):
app/models/invoice.rb:17:in `strip_commas'
app/controllers/invoices_controller.rb:35:in `update'
You can call gsub method over the string but you are calling that on Big Decimal.So try this
def strip_commas
unless self.total_less_tax.blank?
self.total_less_tax = total_less_tax.to_s.gsub(",", ".").to_f
end
end

is that a ruby on rails strange behaviour with overwrite params? Or do I just dont aderstand ruby, again?

pre annotation: I have a solution, I want to understand what happens here, and if this behaviour is intended
edit a try for a better readable shortcut:
if you have the following code in Rails Controller:
def get_page
prepare_anythig params
if is_it_monday?
params=monday_default_paramms
end
finish_any_other_thing params
end
this works only on monday
Following functioning little controller function, not very intersting, I know
class SvgTestController < SiteController
def get_the_page
require "base64"
#main_width="auto"
params[:ci]||=['default']
puts "? params:",params
generate_drawing(params, false)
render ...
end
end
the console shows me how expected:
? params:
{"ci"=>"not default", "controller"=>"svg_test", "action"=>"get_the_page"}
Then I made a small (ok, erroneous or not valid as I now know - or think) change, I extended my get_the_page with 'get params via base64 encode json'
class SvgTestController < SiteController
def get_the_page
require "base64"
#main_width="auto"
params[:ci]||=['default']
# add here
puts "? params:",params
json=params[:json]
puts "json?",json.inspect
if json
plain = Base64.decode64(json)
puts "we are in here:", plain
params=JSON.parse(plain).with_indifferent_access
puts "? params now:",params
end
# end
puts "? params:",params
generate_drawing(params, false)
render ...
end
end
Solution working fine and the output like this:
? params:
{"json"=>"eyJjaSI6eyIwMDAwMDAwMDAyMDQ4MDgiOnsic3J2IjoxfX19", "controller"=>"svg_test", "action"=>"get_the_page", "ci"=>["default"]}
json?
"eyJjaSI6eyIwMDAwMDAwMDAyMDQ4MDgiOnsic3J2IjoxfX19"
we are in here:
{"ci":{"000000000204808":{"srv":1}}}
? params now:
{"ci"=>{"000000000204808"=>{"srv"=>1}}}
? params:
{"ci"=>{"000000000204808"=>{"srv"=>1}}}
later I got, working not with JSON-logic
NoMethodError in SvgTestController#get_the_page
undefined method `[]' for nil:NilClass
and my console shows me:
? params:
{"ci"=>"10.203.192.83", "controller"=>"svg_test", "action"=>"get_the_page"}
json?
nil
? params:
_(nothing to read here)_
So ruby overwrites my params (ok its a method, my fault) even if not in if ... end?
Again I ask: Is this wanted? And if, how to prevent such errors without knowing all and all the time about whats behind words like params?
edit
My solution, but not the answer to my question
...
params_used=params
json=params[:json]
if json
plain = Base64.decode64(json)
params_used=JSON.parse(plain).with_indifferent_access
end
puts "? params:",params_used
generate_drawing(params_used, false)
I think the "error" is because you're actually creating a variable. Annotation of your code:
def get_the_page
require "base64"
#main_width="auto"
params[:ci]||=['default'] # params method
# you modified #params, a mutable hash
# add here
puts "? params:",params # params method
json=params[:json] # params method
# you accessed #params[:json]
puts "json?",json.inspect
if json
plain = Base64.decode64(json)
puts "we are in here:", plain
params=JSON.parse(plain).with_indifferent_access # params variable
puts "? params now:",params # params variable
end
# end
puts "? params:",params # params variable
generate_drawing(params, false) # params variable
render ...
end
What's happening, I'd wager, is that the Ruby interpreter picks up the fact that a variable named params continues to be used after if block, so proceeds to initialize it (to nil) immediately before your if block irrespective of whether the block is visited or not.

Rails Method Ignoring Default Param - WHY?

I am at a loss as to why this is happening. I have the following function:
def as_json(options = {})
json = {
:id => id,
# ... more unimportant code
}
unless options[:simple]
# ... more unimportant code
end
json
end
It works most of the time, but in one particular partial where I call this:
window.JSONdata = <%= #day.to_json.html_safe %>
I get the following error:
ActionView::Template::Error (You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.[]):
Pointing to the line "unless options[:simple]". As far as I can tell, the options hash is nil - thus the method is ignoring the default param assignment. WHY? I can fix this by changing the method to:
def as_json(options)
options ||= {}
json = {
:id => id,
# ... more unimportant code
}
unless options[:simple]
# ... more unimportant code
end
json
end
Does this make any sense to anyone!? Most appreciative for your help.
This is because you're using to_json, which has a default options of nil. to_json will eventually call as_json and pass the nil as options.
Here's where it happens on the Rails source code. First, to_json is defined with the default options of nil.
# https://github.com/rails/rails/blob/v3.0.7/activesupport/lib/active_support/core_ext/object/to_json.rb#L15
def to_json(options = nil)
ActiveSupport::JSON.encode(self, options)
end
Eventually it will arrive here.
# https://github.com/rails/rails/blob/v3.0.7/activesupport/lib/active_support/json/encoding.rb#L41
def encode(value, use_options = true)
check_for_circular_references(value) do
jsonified = use_options ? value.as_json(options_for(value)) : value.as_json
jsonified.encode_json(self)
end
end
As you see, as_json is called with value.as_json(options_for(value)) and options_for(value) will return the default value of to_json, which is nil.

Resources