Undefined method each for nil:NilClass in erb template - ruby

I'm trying to loop through and array and have checked to make sure it is being passed correctly to the template, yet am hitting the error.
The template:
<% if defined?(source[:blacklist]) %>
"blacklist": [
<% source[:blacklist].each do |listed| %>
"<%= listed %>"
<% end %>
],
<% end %>
output of source[:blacklist] when no loop:
"[\"/var/log/httpd/access.log*\", \"/var/log/httpd/error.log*\", \"/var/log/httpd/ssl_request_log\", \"/var/log/httpd/access_log\", \"/var/log/httpd/error_log\"]"
error:
undefined method `each' for nil:NilClass

Your array is not present, if it was it would actually be a string.
Using defined?(source[:blacklist]) presents an issue as it will return true if it's not an array, e.g. defined? nil is "nil" which is truthy.
Step 1: convert to array
If you cannot change how the data is being generated, parse it into a Ruby array, defaulting to an empty array if there is an unexpected data or none at all.
blacklist = source[:blacklist].gsub(/(\­[\"|\"\])/­, '').s­plit('", "') || []
Step 2: loop if the array exists and with content
<% if not blacklist.empty? %>

If source[:blacklist] is nil then defined? source[:blacklist] will return the string "method" and that's "truthy".
So it will fall through and you'll get the error you see... Undefined method each for nil:NilClass
When you say "output of source with no loop"... is that in the controller or did you check the output in the erb file? It could be the value's not being passed to the erb, and you typically want to use instance variables to pass data to html.erb files.
Also, you should note that the output you show for source[:blacklist] is actually a string, not an array, so even if it was passed you would still get an error on the each method.

Related

erb file with chef syntax

Trying to output the contents of
node['a'] = {:b "1" :c "2"}
by doing this:
a:
<% a = node['a'] %>
b: <% a[:b] %>
c: <% a[:c] %>
<% end %>
to generate this:
a:
b: 1
c: 2
However not entirely sure the correct syntax to do this being new to ruby, chef and erb.
Okay, so let's rewind a bit. The first thing is that you generally don't want to reference node attributes directly in templates. In some cases like attributes coming from Ohai it can be okay as a shorthand, but for important data I would also pass it in via the variables property like this:
template '/etc/whatever.conf' do
source 'whatever.conf.erb'
variables a: node['a']
end
With that in place we've now expose the data as a template variable. The second piece of improving this is to let Ruby do the heavy lifting of generating YAML. We can do this using the .to_yaml method in the template:
<%= #a.to_yaml %>
That should be all you need!

Iterate over a singleton or multiple of a returned DataMapper class

I have the following code
if admin_authorized?
#allschools = School.all
elsif faculty_authorized?
#allschools = School.get(Faculty.get(session[:faculty_id]))
end
I am getting this error
undefined method `each' for #<School:0x007f88a1360318>
#allschools will either be an array of schools or a singleton school. I need to iterate over this list in the view, like so:
<% #allschools.each do |s| %>
<%= f_optionselected(s.id.to_s, params[:school], s.name) %>
<% end %>
I've tried to do if statements with #allschools.count, #allschools.typeof(Array), ....
Should I use two different variables and a PHP type isset() statment to determine which block to display? Or is there a way to iterate over the statement in some Ruby way?
School.all returns an ActiveRecord::Relation and you can iterate through it, as you do with each. I think School.get returns a single School instance, right? Try to wrap it into an Array:
#allschools = [School.get(Faculty.get(session[:faculty_id]))]

How can I access elements of an array of hashes in a view? (Sinatra)

I'm quite new in web development and I am practicing with Sinatra. I am trying to access each element of each hash that is kept inside an array. I googled around and I did not find a clear answer/reason to why I cannot do that in the way I am doing it. Could you please help me with it? Thanks.
what is inside my files:
app.rb
get '/' do
#jobs = [{"jobId"=>25347483, "employerId"=>382326},
{"jobId"=>34543, "employerId"=>3233},
{"jobId"=>90009, "employerId"=>94949},
{"jobId"=>5005004, "employerId"=>95959}
]
end
index.erb
<body>
<% #jobs.each do |job| %>
<p><%= job['jobId'] %></p>
<% end %>
</body>
error that I get:
NoMethodError at /
undefined method `bytesize' for {"jobId"=>25347483, "employerId"=>382326}:Hash
I was getting an error because I couldn't do that!
As from: http://www.sinatrarb.com/intro.html
"Return Values
The return value of a route block determines at least the response body passed on to the HTTP client, or at least the next middleware in the Rack stack. Most commonly, this is a string, as in the above examples. But other values are also accepted.
You can return any object that would either be a valid Rack response, Rack body object or HTTP status code:
An Array with three elements: [status (Fixnum), headers (Hash), response body (responds to #each)]
An Array with two elements: [status (Fixnum), response body (responds to #each)]
An object that responds to #each and passes nothing but strings to the given block
A Fixnum representing the status code"

Parsing XML and how to handle nested Arrays and Hashes

I'm using this instance variable:
#response = HTTParty.get("http://www.bart.gov/dev/eta/bart_eta.xml")
I'm trying to parse the xml using rails 3.2:
<% #response.each do |r| %>
<% r.each do |root| %>
<%= root.class %>
<% end %>
<% end %>
The output is
String Hash
I get "String Hash" for "root.class". I don't understand how it can be "String Hash," I would like to implement another "each" method to go deeper in the xml layers.
What does "String Hash" mean?
Your #response object is of the type HTTParty::Response.
It looks like it's wrapping an array with two values in it: the first value is a String, "root", and the second value is a Hash.
Since you have no line breaks in your ERB code, as you iterate through the array it is printing out String and Hash on the same line.
Try using root.inspect to dig deeper into what values you're actually iterating through.

Array of Ruby objects returning strings on each method. Why?

Useful additional info: I am using the decent_exposure gem so this might be the issue - correcting the code below:
expose(:get_filter_tags) do
if params[:filter_tag_names]
filter_tag_names = Array(params[:filter_tag_names].split(" "))
filter_tags = Array.new
filter_tag_names.each do |f|
t = Tag.find_by_name(f)
filter_tags << t
end
end
end
So, something funny happens when I call this in the view:
query string ?utf8=✓&filter_tag_names=test
<% get_filter_tags.each do |ft| %>
<%= ft.name %>
<% end %>
Error message: undefined method `name' for "test":String
Why is this trying to call name on a string not a Tag object? If I put the following in the view, and have jut one filter_tag_names item
def getfiltertag
Tag.find_by_name(params[:filter_tag_names])
end
#view
<%= getfiltertag.name %>
query string: ?utf8=✓&filter=test
like above then I can call name just fine, so obviously I am doing something wrong to get an array of strings instead of objects. I just don't know what. Any suggestions?
Your problem is that each returns self — so if you write filter_tag_names.each, it returns filter_tag_names. You could fix this by explicitly returning filter_tags, but more idiomatically, you could just rewrite it as:
expose(:get_filter_tags) do
if params[:filter_tag_names]
filter_tag_names = Array(params[:filter_tag_names].split(" "))
filter_tag_names.map {|f| Tag.find_by_name(f) }
end
end
Just as an aside, this method will return nil if there aren't any filter tag names. You may want to do that, or you might want to return an empty collection to avoid exceptions in the calling code.

Resources