undefined method `offset' for an array in Ruby - ruby-on-rails

I am using the following step in my pagination method steps:
Edit : nodes2 is an array.
nodes = nodes2.take(per_page).offset((page_number.to_i - 1) * per_page)
#length = (nodes2.count/per_page).ceil
I get the following error:
undefined method 'offset' for #<Array:0x00000005905128>
Basically I am using the following steps and they work fine as I get the objects out of .leaves method, but am not sure how to deal with the array
nodes = inode.leaves.limit(per_page).offset((page_number.to_i - 1) * per_page)
#length = (inode.leaves.count/per_page).ceil
Could some one pls help me out. Thanks!

take is a method on Array. When you run it against nodes2 (which I assume is an ActiveRecord::Relation object), it's doing the equivalent of this:
nodes = nodes2.to_a.take(per_page)...
So because of this, offset is being run on an Array object. You could try making take(...) be the last method call, that way offset is still being run against ActiveRecord:
nodes = nodes2.offset((page_number.to_i - 1) * per_page).take(per_page)

Related

TypeError: no implicit conversion of Fixnum into Hash - Ruby

Did I try google?
Yes, I tried stack overflow, google, rubydocs, bunch of websites but there are minimal results to this and it's only ever mentioned indirectly. So yes, I did a lot of searching.
What's working?
I run the following query:
requests = Request.where("customer_id = ?
AND request_method != ?
AND request_time
BETWEEN ? AND ?",
customer.id, "OPTIONS", start_time, end_time).group('request_time')
As a result I get a bunch of values from the Database which look like this and this is CORRECT:
#<ActiveRecord::Relation[#<Request id: 171792, request_time: "2022-04-04 14:07:20">,
#<Request id: 171787, request_time: "2022-04-04 14:06:02">...]
NOTE: I didn't paste all the values because they have a similar structure.
What's the problem?
After running the query I want to pass it to the variable dates_init_hash = {} and merge it whilst counting into data[:requests]:
dates_init_hash = {}
(start_time.to_date..end_time.to_date).each do |date|
dates_init_hash[date] = 0
end
data[:requests] = dates_init_hash.merge(requests.count)
Unfortunately, I always seem to be getting the error:
ERROR -- : TypeError: no implicit conversion of Fixnum into Hash
Expected
I should be getting a Hash like the following:
{ "2022-03-24"=>2, "2022-03-25"=>1, "2022-03-28"=>3, "2022-03-29"=>11}
What I tried
I tried to convert the results to a hash before passing it over but this gave me the error that the .to_h method doesn't exist
data[:requests] = dates_init_hash.merge({requests: requests.count }) works half-way still causing errors
Questions
Why am I getting a Fixnum and why won't this work? How can I improve this? What would be the right way to solving this? I appreciate any kind of help.
Why is the error happening?
You are getting the error because when you run:
data[:requests] = dates_init_hash.merge(requests.count)
dates_init_hash is a hash, and requests.count is a number. So you are trying to merge a number into a hash, what is not allowed.
How can I fix it?
If what you want is to have the dates_init_hash with a mapping date => number of requests that date, you can do the following:
# initializes dates_init_hash with desired dates
dates_init_hash = {}
(start_time.to_date..end_time.to_date).each do |date|
dates_init_hash[date.iso8601] = 0
end
# iterates over reuests and add 1 to the date in dates_init_hash for each request in the desired date
requests.each do |request|
date = Date.parse(request[:request_time]).iso8601
next if dates_init_hash[date].nil?
dates_init_hash[date] += 1
end
Then, dates_init_hash will be something like
{"2022-04-04"=>1, "2022-04-05"=>0, "2022-04-06"=>1, "2022-04-07"=>0}

Initialize two dimensional object array returns fatal error

I want to create a 2d array of teams. Therefore, I can reach with like Teams[0][i] or Teams[1][0]. First print returns correct value but second one returns fatal index out of range.
self.teams = [self.first_array , self.second_array]
print(self.teams[0][0].name)
print(self.teams[1][0].name)
Try doing:
self.teams = [self.first_array , self.first_array]
If this works, then there's something wrong with self.second_array specifically. Your syntax looks fine except we can't see the rest of the code, particularly where you're initializing self and its properties.

How to find the difference between two arrays after calling a method

I'm trying to subtract the earliest date from two arrays:
def days_pending
start = [object.created_at]
finish = [Time.now.strftime('%Y-%m-%d')]
if object.app_sign_date
start.push(object.app_sign_date)
end
if object.submitted_date
start.push(object.submitted_date)
end
if object.inforce_date
finish.push(object.inforce_date)
end
if object.closed_date
finish.push(object.closed_date)
end
finish.min - start.min
I have no problem calling min on the arrays, but have a problem calling the min method and then subtracting. I get NoMethodError: undefined method-' for "2015-01-01":String`.
the array finish has first element as string not the date. you need to add appropriate object instead ie. date or datetime
finish = [Time.now]
or
finish = [DateTime.now]
After calling Time.now.strftime('%Y-%m-%d'), what you got is a string.
Change to Time.now should work.
If you need the output to be in the form "2015-01-01" you could use parse:
Time.parse(finish.min) - start.min

Call a method from constructed string in Ruby / Rails

I've got a problem in doing some metaprogramming in Ruby / Rails which must be minor, but I can't get the clue.
I wan't to assign values to an active record relation, with my model having attributes:
MyModelClass.p1_id,
.p2_id,
...
.p8_id
SecondModel.position #Integer in (1..8)
I now want to do the following
sms = SecondModel.where(:xyz => 'bla')
sms.each do |sm|
mmc = MyModellClass.first
mmc.#somehow construct method here = sm.id
end
So that somehow this is accomplished
mmc.p1_id = sm.id
mmc.p2_id = sm.id
..
mmc.p8_id = sm.id
To sum up: I want to create that p*n*_id stuff dynamically, but I can't find out, how to tell Ruby, that this should be a method. I tried so far:
mmc.send('p#{sm.position.to_s}_id'.to_sym) = sm.id
But this doesn't work. Any clues?
You were close. Try this:
mmc.send("p#{sm.position.to_s}_id=", sm.id)
Here we call the method with = and pass the value of attribute as the second argument of send

undefined method `gsub' for nil:NilClass

I'm newvbie in ruby on rails.. I'm having problem with gsub.. I everytime I go to the list of my store page it says "undefined method `gsub' for nil:NilClass"..
here is mycode :
def self.search(search_val, page = 1)
#search_val = search_val.gsub("'", "\\\\'")
search_query = "store_id LIKE '%#{ #search_val }%' OR english_name LIKE '%#{ #search_val }%' OR chinese_name LIKE '%#{ #search_val }%'"
select("jos_store.id, store_id, english_name, chinese_name, store_manager, delivery_area,year, week").joins("LEFT OUTER JOIN (SELECT id as store_replenishment, store, MAX(stock_movement) AS stock_movement FROM jos_store_replenishment GROUP BY store) AS replenishment ON replenishment.store = jos_store.id").joins("LEFT OUTER JOIN jos_stock_movement ON jos_stock_movement.id = replenishment.stock_movement").where(search_query).order("year DESC, week DESC").paginate :page => page, :per_page => 15
end
thanks in advance
A good practice is doing .to_s when you are using string methods.
You can use the & operator on search_val. It allows you to avoid null pointer exceptions without adding additional checks or using to_s to convert a string to a string.
So, you'll have something like this:
#search_val = search_val&.gsub("'", "\\\\'")
You can read more on the safe navigation operator here: http://mitrev.net/ruby/2015/11/13/the-operator-in-ruby/
This means that search_val is in fact nil. You can easily verify this by printing out the value of search_val.
I'm not sure if this is your case, but the same undefined method gsub for nil:NilClass error happened with me after a few rollbacks and migrations.
Then, I restarted the server and works. Maybe this could be the case for some people that reached this topic searching on Google.

Resources