How can I get last only if more than one? - ruby-on-rails

In rails I have this:
page_classes.split(/\s/).last
Sometimes page_classes doesn't contain any whitespace and I get the error:
undefined method `last' for nil:NilClass
How can I get the last unless there is only one?

try this
page_classes.split(/\s/).try(:last)

The problem is about your page_classes object.
page_classes.split("\s").last
Calling .last will ALWAYS work with an array (even empty). If you have probems, it means your page_classes object is nil or not a string that can be processed by split().

Related

Trouble Accessing Ruby Array and Hash Value

I am making an api call and receiving the following response (it's long, so I'm showing the important part):
... "fields":{"count"_1:["0"],"count_2":["5"]} ...
when I do:
call["fields"]["count_1"]
It returns
["0"]
I need it to give me just the integer. I tried:
call["fields"]["count_1"][0]
And I also tried:
call["fields"]["count_1"][0].to_i
I'm running this in Rails and it gives me the error:
undefined method `[]' for nil:NilClass
But it's not working.
Try as below using String#to_i
call["fields"]["count_1"][0].to_i # => 0
Some tips:
Try wrapping the API response in JSON.parse(...). That is, if you're not making the call via a gem that already does this. This might require 'json'.
Try call['fields']['count_1'].first.to_i
Do some debugging: check the value of call.class, call['fields'].class and call['fields']['count_1'].class. The last one should definitly be an Array.
Add an if clause to check if call['fields'][['count_1'].is_empty?.
Look for typos :)
For some reason the API call was making the zeros nil instead of zero. Thanks for all your help.

HttpParty::Response and try(:parsed_response) weird behavior

I've tried to use ActiveSupport's (2.3-stable) try() on an instance of HttpParty::Response. I've got a pretty strange behavior:
> ro.parsed_response
{"error"=>"RecordInvalid", "description"=>"Record validation errors", "details"=>{"email"=> [{"description"=>"Email: foo#bar.com is already taken by another user"}]}}
> ro.try(:parsed_response)
NoMethodError Exception: undefined method `parsed_response' for #<Hash:0x11397d5d8>
In the first example, I send the parsed_response message to ro by using the dot notation. It works fine. In the second one, I try to call it using ActiveSupport's try(), and it (surprisingly) raises the NoMethodError exception.
Shouldn't try() have returned nil in this case? And why doesn't it find the "parsed_response" method, if I can call it using the dot notation, as seen in the first example?
Thanks in advance!
Have no idea how, but seems like ro object was "transfered" into a hash that has been sent a parsed_response method.
In Rails 2.3#ruby 1.8 undefined method for object raises an exception.
Besides, docs stay only for calling try on nil object and nothing about the object that doesn't have a specific method:
Unlike that method however, a NoMethodError exception will not be
raised and nil will be returned instead, if the receiving object is a
nil object or NilClass.

How to run each loop on single item?

I'm pulling all associated objects of a particular object, and doing an each_with_index on it.
ie. subscription.transactions.each_with_index
But when there is only one transaction (and thus it's not an array), I get an undefined method 'each' error.
How do I get around this and basically just run the each once?
You can do
Array(subscription.transactions).each_with_index
You can also do this
[subscription.transactions].flatten.each_with_index

How can I find the index of the last item in an array?

My Array:
(rdb:381) pp params[:payments]
{"0"=>{":amount_paid"=>"100.00", ":date_paid"=>"2/27/2008"},
"1"=>{":amount_paid"=>"80.00", ":date_paid"=>"3/27/2008"},
"2"=>{":amount_paid"=>"100.00", ":date_paid"=>"5/8/2008"}}
I don't believe this is an object . Performing params[:payments].last returns this :
NoMethodError Exception: undefined method `last' for #<ActiveSupport::HashWithIndifferentAccess:0x1065e8448>
I am trying to find the index of that last item. In this case, the answer is 2, or "2"
Hey, your array is actually a hash. You could maybe get the index of the last key by doing something like params[:payments].keys.map(&:to_i).max.to_s
It would be even better to pass an actual array back. How are you generated the :payments option?
Your value is a Hash, not an Array, so it doesn't have ordering or indexes, unless you are on Ruby 1.9

Ruby: Dynamically calling available methods raising undefined method (metaprogramming)

I have an Activerecord object called Foo:
Foo.attribute_names.each do |attribute|
puts Foo.find(:all)[0].method(attribute.to_sym).call
end
Here I'm calling all attributes on this model (ie, querying for each column value).
However, sometimes, I'll get an undefined method error.
How can ActiveRecord::Base#attribute_names return an attribute name that when converted into its own method call, raises an undefined method error?
Keep in mind this only happens on certain objects for only certain methods. I can't identify a pattern.
Thank you.
The NoMethodError should be telling you which method does not exist for what object. Is it possible that your find returns no record? In that case, [][0] is nil and you will get a NoMethodError for sure.
I would use .fetch(0) instead of [0], and you will get a KeyError if ever there is no element with index 0.
Note: no need for to_sym; all builtin methods accept name methods as strings or symbols (both in 1.8 and 1.9)
Maybe something to do with access? Like if a class has an attr_protected attribute, or something along that line. Or for attributes that are not database columns, which have no accessors defined?

Resources