How to run each loop on single item? - ruby-on-rails

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

Related

How to move a record within a collectionproxy in rails

In my rails app I have a collectionproxy that is an array (I think) of records. I want to take a record from the middle of the array and put it at the beginning. I don't know the position of the item, but I can find it using an attribute on user model. It seems like some methods aren't available to use on a collectionproxy.
I tried:
user_images = user.images
user_images.insert(0, user_images.delete(user.images.find_by_id(user.primary_image_id))
but got an error that I gave 2 arguments but it expected 1. I'm guessing because the insert method that is used on arrays isnt the same method that is used on collectionproxies. What's the best way to do this?
Edit: I just need this to display the items in the view, I don't need to change at the database level.
As very few methods are available for collection proxy, first change the collection proxy to array and then manipulate it.
Here is the code to do so,
user_images = user.images.to_a //converted collection to array
user_images.unshift(user_images.detect{ |image| image.id == user.primary_image_id}).uniq //used unshift
puts user_images
The magic we have done here is detect the images that's the primary image of the user and unshift into array
The unshift adds the object in the beginning.
Now remove the duplicated oject which is already there at someplace by using uniq.
That's it your required objects comes first into the array and you can use this in the view as active record collection is used.
It looks like there's currently no way to add to the beginning of a CollectionProxy. The prepend and sort methods were removed. Here's the API for the deprecated prepend method:
http://apidock.com/rails/v4.2.1/ActiveRecord/Associations/CollectionProxy/prepend
You could re-think this slightly, and use the append or << operator along with delete to copy elements to the end of the collection, and delete them from the middle. It's not ideal, but it might be a workaround until you have a better solution.

How can I get last only if more than one?

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().

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.

How to get result of the previous action

Hi Inside rails console you can get the result of the previous operation with _ Is there any way to do such a thing inside ruby program?
everything in Ruby is an object, so think about it, if any returned object is not assigned a reference then it will be marked for garbage collection, so no there is no way other than to assign a returned object to a variable!
You can do this with irb (and programs that improve on irb) - it's not specific to Rails. But apart from that, I'm not aware of being able to do what you want.

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