Ruby Newbie strftime Time.Now - ruby-on-rails

I have the following written in ruby
t = Time.now
t.strftime("%Y-%d-%m")
SCHEDULER.every '1m', :first_in => 0 do |job|
send_event('gmail_gh', {current: gmail.inbox.count(:after => Date.parse(t)), older: gmail.inbox.count})
But i get this error
scheduler caught exception:
can't convert Time into String
/var/dashing/cdmdash/jobs/gmail_gh.rb:21:in `parse'
/var/dashing/cdmdash/jobs/gmail_gh.rb:21:in `block in <top (required)>'
/usr/local/rvm/gems/ruby-1.9.3-p327/gems/rufus-scheduler-2.0.17/lib/rufus/sc/jobs.rb:231:in `call'
/usr/local/rvm/gems/ruby-1.9.3-p327/gems/rufus-scheduler-2.0.17/lib/rufus/sc/jobs.rb:231:in `trigger_block'
/usr/local/rvm/gems/ruby-1.9.3-p327/gems/rufus-scheduler-2.0.17/lib/rufus/sc/jobs.rb:191:in `block in trigger'
/usr/local/rvm/gems/ruby-1.9.3-p327/gems/rufus-scheduler-2.0.17/lib/rufus/sc/scheduler.rb:416:in `call'
/usr/local/rvm/gems/ruby-1.9.3-p327/gems/rufus-scheduler-2.0.17/lib/rufus/sc/scheduler.rb:416:in `block in trigger_job'
I think it has something to do with the t variable and it not being a truing, I am new to Ruby so I am abit stuck

If you look at the gem documentation, you will see that the :after and :before params take in a date in the format of YYYY-MM-DD.
From the gem Readme:
gmail.inbox.count(:after => Date.parse("2010-02-20"), :before => Date.parse("2010-03-20"))
gmail.inbox.count(:on => Date.parse("2010-04-15"))
Your code is passing in YYYY-DD-MM which is likely causing the error.
Edit
When you call strftime on a datetime object, it doesn't modify the object - only returns the string notation based on format you give.
As a result, the Date.parse(t) is still getting Time.now was a parameter.
Try this:
t = Time.now.strftime("%Y-%m-%d")
Date.parse(t)

Related

money-rails, Money#== supports only zero numerics

I'm using the money-rails gem in my Rails application. It have worked perfectly until now, but I've recently started getting the following error:
Money#== supports only zero numerics
I'm not really sure what caused this or how to solve it. I have recently run bundle update so I guess that something have been updated. My gemfile looks like this:
gem 'money-rails', '~>1'
gem 'eu_central_bank', "~>1.3.0"
My implementation looks like this:
# model
monetize :price_in_cents
# fetch / converting currencies
eu_bank = EuCentralBank.new
Money.default_bank = eu_bank
eu_bank.update_rates
converted_price = eu_bank.exchange_with(Money.new(price_to_convert * 100, from_currency), to_currency)
This have as I mentioned worked before, so I'm not sure what is breaking it.
Any ideas?
Update
To test I tried with the following.
money = Money.new(100, from_currency)
Then I got the same error as before. But if I tried:
money = Money.new(0, from_currency)
It seems to work. I find that a bit strange.
Update
Here is the backtrace from when I try to save the record:
["/Users/[user]/.rvm/gems/ruby-2.5.1/gems/money-6.11.3/lib/money/money/arithmetic.rb:70:in =='", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activemodel-5.1.6/lib/active_model/validations/numericality.rb:22:in!='", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activemodel-5.1.6/lib/active_model/validations/numericality.rb:22:in validate_each'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activemodel-5.1.6/lib/active_model/validator.rb:150:inblock in validate'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activemodel-5.1.6/lib/active_model/validator.rb:147:in each'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activemodel-5.1.6/lib/active_model/validator.rb:147:invalidate'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:413:in block in make_lambda'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:197:inblock (2 levels) in halting'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:601:in block (2 levels) in default_terminator'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:600:incatch'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:600:in block in default_terminator'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:198:inblock in halting'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:507:in block in invoke_before'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:507:ineach'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:507:in invoke_before'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:130:inrun_callbacks'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:827:in _run_validate_callbacks'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activemodel-5.1.6/lib/active_model/validations.rb:405:inrun_validations!'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activemodel-5.1.6/lib/active_model/validations/callbacks.rb:114:in block in run_validations!'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:97:inrun_callbacks'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:827:in _run_validation_callbacks'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activemodel-5.1.6/lib/active_model/validations/callbacks.rb:114:inrun_validations!'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activemodel-5.1.6/lib/active_model/validations.rb:335:in valid?'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activerecord-5.1.6/lib/active_record/validations.rb:65:invalid?'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activerecord-5.1.6/lib/active_record/validations.rb:82:in perform_validations'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activerecord-5.1.6/lib/active_record/validations.rb:50:insave!'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activerecord-5.1.6/lib/active_record/attribute_methods/dirty.rb:43:in save!'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activerecord-5.1.6/lib/active_record/transactions.rb:313:inblock in save!'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activerecord-5.1.6/lib/active_record/transactions.rb:384:in block in with_transaction_returning_status'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activerecord-5.1.6/lib/active_record/connection_adapters/abstract/database_statements.rb:235:inblock in transaction'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activerecord-5.1.6/lib/active_record/connection_adapters/abstract/transaction.rb:194:in block in within_new_transaction'", "/Users/[user]/.rvm/rubies/ruby-2.5.1/lib/ruby/2.5.0/monitor.rb:226:inmon_synchronize'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activerecord-5.1.6/lib/active_record/connection_adapters/abstract/transaction.rb:191:in within_new_transaction'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activerecord-5.1.6/lib/active_record/connection_adapters/abstract/database_statements.rb:235:intransaction'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activerecord-5.1.6/lib/active_record/transactions.rb:210:in transaction'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activerecord-5.1.6/lib/active_record/transactions.rb:381:inwith_transaction_returning_status'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activerecord-5.1.6/lib/active_record/transactions.rb:313:in save!'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activerecord-5.1.6/lib/active_record/suppressor.rb:46:insave!'", "/Users/[user]/Documents/Development/wondery/[appname]/lib/importers/bts_wholesaler_importer.rb:245:in block in set_supported_currencys_for_product_variant'", "/Users/[user]/Documents/Development/wondery/[appname]/lib/importers/bts_wholesaler_importer.rb:240:ineach'", "/Users/[user]/Documents/Development/wondery/[appname]/lib/importers/bts_wholesaler_importer.rb:240:in set_supported_currencys_for_product_variant'", "/Users/[user]/Documents/Development/wondery/[appname]/lib/importers/bts_wholesaler_importer.rb:224:inset_up_product_variant'", "/Users/[user]/Documents/Development/wondery/[appname]/lib/importers/bts_wholesaler_importer.rb:208:in match_product_variant_to_product'", "/Users/[user]/Documents/Development/wondery/[appname]/lib/importers/bts_wholesaler_importer.rb:84:inblock in get_products_from_api_data'", "/Users/[user]/Documents/Development/wondery/[appname]/lib/importers/bts_wholesaler_importer.rb:75:in map'", "/Users/[user]/Documents/Development/wondery/[appname]/lib/importers/bts_wholesaler_importer.rb:75:inget_products_from_api_data'", "/Users/[user]/Documents/Development/wondery/[appname]/lib/importers/bts_wholesaler_importer.rb:25:in import'", "(irb):2:inirb_binding'", "/Users/[user]/.rvm/rubies/ruby-2.5.1/lib/ruby/2.5.0/irb/workspace.rb:85:in eval'", "/Users/[user]/.rvm/rubies/ruby-2.5.1/lib/ruby/2.5.0/irb/workspace.rb:85:inevaluate'", "/Users/[user]/.rvm/rubies/ruby-2.5.1/lib/ruby/2.5.0/irb/context.rb:380:in evaluate'", "/Users/[user]/.rvm/rubies/ruby-2.5.1/lib/ruby/2.5.0/irb.rb:491:inblock (2 levels) in eval_input'", "/Users/[user]/.rvm/rubies/ruby-2.5.1/lib/ruby/2.5.0/irb.rb:623:in signal_status'", "/Users/[user]/.rvm/rubies/ruby-2.5.1/lib/ruby/2.5.0/irb.rb:488:inblock in eval_input'", "/Users/[user]/.rvm/rubies/ruby-2.5.1/lib/ruby/2.5.0/irb/ruby-lex.rb:246:in block (2 levels) in each_top_level_statement'", "/Users/[user]/.rvm/rubies/ruby-2.5.1/lib/ruby/2.5.0/irb/ruby-lex.rb:232:inloop'", "/Users/[user]/.rvm/rubies/ruby-2.5.1/lib/ruby/2.5.0/irb/ruby-lex.rb:232:in block in each_top_level_statement'", "/Users/[user]/.rvm/rubies/ruby-2.5.1/lib/ruby/2.5.0/irb/ruby-lex.rb:231:incatch'", "/Users/[user]/.rvm/rubies/ruby-2.5.1/lib/ruby/2.5.0/irb/ruby-lex.rb:231:in each_top_level_statement'", "/Users/[user]/.rvm/rubies/ruby-2.5.1/lib/ruby/2.5.0/irb.rb:487:ineval_input'", "/Users/[user]/.rvm/rubies/ruby-2.5.1/lib/ruby/2.5.0/irb.rb:428:in block in run'", "/Users/[user]/.rvm/rubies/ruby-2.5.1/lib/ruby/2.5.0/irb.rb:427:incatch'", "/Users/[user]/.rvm/rubies/ruby-2.5.1/lib/ruby/2.5.0/irb.rb:427:in run'", "/Users/[user]/.rvm/rubies/ruby-2.5.1/lib/ruby/2.5.0/irb.rb:383:instart'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/railties-5.1.6/lib/rails/commands/console/console_command.rb:62:in start'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/railties-5.1.6/lib/rails/commands/console/console_command.rb:17:instart'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/railties-5.1.6/lib/rails/commands/console/console_command.rb:97:in perform'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/thor-0.20.0/lib/thor/command.rb:27:inrun'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/thor-0.20.0/lib/thor/invocation.rb:126:in invoke_command'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/thor-0.20.0/lib/thor.rb:387:indispatch'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/railties-5.1.6/lib/rails/command/base.rb:63:in perform'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/railties-5.1.6/lib/rails/command.rb:44:ininvoke'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/railties-5.1.6/lib/rails/commands.rb:16:in <top (required)>'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activesupport-5.1.6/lib/active_support/dependencies.rb:292:inrequire'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activesupport-5.1.6/lib/active_support/dependencies.rb:292:in block in require'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activesupport-5.1.6/lib/active_support/dependencies.rb:258:inload_dependency'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activesupport-5.1.6/lib/active_support/dependencies.rb:292:in require'", "/Users/[user]/Documents/Development/wondery/[appname]/bin/rails:9:in'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activesupport-5.1.6/lib/active_support/dependencies.rb:286:in load'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activesupport-5.1.6/lib/active_support/dependencies.rb:286:inblock in load'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activesupport-5.1.6/lib/active_support/dependencies.rb:258:in load_dependency'", "/Users/[user]/.rvm/gems/ruby-2.5.1/gems/activesupport-5.1.6/lib/active_support/dependencies.rb:286:inload'", "/Users/[user]/.rvm/rubies/ruby-2.5.1/lib/ruby/site_ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in require'", "/Users/[user]/.rvm/rubies/ruby-2.5.1/lib/ruby/site_ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:inrequire'", "-e:1:in `'"]
The error comes from a numericality validation on your model.
Money gem does not allow to compare a money object with a Number, unless thee number is zero. Otherwise it expects you to compare Money with Money.
In irb you can try:
```ruby
2.5.1 :006 > Money.new(1000, "USD") != Money.new(1000, "USD")
=> false
2.5.1 :007 > Money.new(1000, "USD") != 1000
Traceback (most recent call last):
4: from /Users/andi/.rvm/rubies/ruby-2.5.1/bin/irb:11:in `<main>'
3: from (irb):7
2: from (irb):7:in `!='
1: from /Users/andi/.rvm/gems/ruby-2.5.1/gems/money-6.12.0/lib/money/money/arithmetic.rb:70:in `=='
ArgumentError (Money#== supports only zero numerics)
2.5.1 :008 > Money.new(1000, "USD") != 0
=> true
```
I believe that this error makes sense, as you can't really compare an arbitrary number with an amount of money in a given currency.
The money-rails gem again comes with it's own validators:
https://github.com/RubyMoney/money-rails#numericality-validation-options
Your backtrace shows that you are using the rails numericality validator instead.
You might also come across this error when you are writing specs:
expect(order.subtotal).to eq 123.45
# ArgumentError:
# Money#== supports only zero numerics
expect(order.subtotal).to eq Money.new(12345)
# works!
Money Rails automatically adds "_cents" to the attribute you are monetizing. Then it creates an instance of that model.price which includes
<Money fractional:1500 currency:DKK>
Hence, you cannot do model.price + 10 as it would cause the error you are getting.
You may therefore want to monetize price_to_convert, or any other value you are working with so that you can sum them up, etc.
Create a new migration file e.g.
rails g migration AddMoneytizeToOrders
change migration file so that it reads as follow (change column/attribute to your values)
class AddMonetizeToOrder < ActiveRecord::Migration[6.0]
def change
add_monetize :orders, :price_to_convert, currency: { present: false }
end
end
In your model you must include
monetize :price_to_convert_cents
then you can work with e.g.(rails c) Order.last.price_to_convert + Model.last.price, etc.
Please note that you cannot use self.[:price_to_convert] as money rails wouldn't understand it and you would get the error
money rails ActiveModel::MissingAttributeError (can't write unknown attribute...
Therefore use self.price_to_convert instead

NoMemoryError: failed to allocate memory - Ruby on Rails

I generated a simple script that on other occasions has worked for me, but this is because the amount of information in the loop generates a NoMemoryError error.
I have 16 GB of memory and also a lot of virtual memory available. When I perform the test, the RAM memory is completely filled.
The script is:
require 'rest-client'
require 'json'
require 'open-uri'
require 'csv'
def self.qos7705egressdiscard_summary
xml = File.read("#{Rails.root}/public/Discard_qos7705egress.xml")
data = RestClient.post("http://10.140.255.1:8080/xmlapi/invoke", xml,{:"Content-Type" => 'application/soap+xml'})
data_parsed = Hash.from_xml(data)
return data_parsed
end
def self.samqos7705egressdiscardtotal_table
tabletotal = Hash.new
data_stats = qos7705egressdiscard_summary['Envelope']['Body']['findResponse']['result']['service.SapEgrQosQueueStatsLogRecord']
data_stats.map do |qosdiscard_device|
#devicetotal = qosdiscard_device["monitoredObjectSiteName"]
#servicetotal = qosdiscard_device["monitoredObjectPointer"]
#porttotal = qosdiscard_device["displayedName"]
#queueIdtotal = qosdiscard_device["queueId"]
#discardinproftotal = qosdiscard_device["droppedInProfOctets"].to_i
#discardoutproftotal = qosdiscard_device["droppedOutProfOctets"].to_i
time_unixtotal = (qosdiscard_device["timeCaptured"]).to_i/1000
#timeCapturedtotal = Time.at(time_unixtotal).strftime("%B %e, %Y at %I:%M %p")
#discardtotal = #discardinproftotal + #discardoutproftotal
#device_int_stats_total = (#devicetotal+#porttotal+#queueIdtotal).to_s
hash = Hash[devicetotal: #devicetotal, servicetotal: #servicetotal, porttotal: #porttotal, queueIdtotal: #queueIdtotal, discardtotal: #discardtotal, device_int_stats_total: #device_int_stats_total, timeCapturedtotal: #timeCapturedtotal, time_unixtotal: time_unixtotal]
tabletotal << hash
#tabletotal.write(hash)
end
end
The exact error is:
NoMemoryError: failed to allocate memory
from /usr/local/lib/ruby/2.2.0/irb/inspector.rb:108:in `inspect'
from /usr/local/lib/ruby/2.2.0/irb/inspector.rb:108:in `block in <module:IRB>'
from /usr/local/lib/ruby/2.2.0/irb/inspector.rb:101:in `call'
from /usr/local/lib/ruby/2.2.0/irb/inspector.rb:101:in `inspect_value'
from /usr/local/lib/ruby/2.2.0/irb/context.rb:383:in `inspect_last_value'
from /usr/local/lib/ruby/2.2.0/irb.rb:661:in `output_value'
from /usr/local/lib/ruby/2.2.0/irb.rb:490:in `block (2 levels) in eval_input'
from /usr/local/lib/ruby/2.2.0/irb.rb:623:in `signal_status'
from /usr/local/lib/ruby/2.2.0/irb.rb:486:in `block in eval_input'
from /usr/local/lib/ruby/2.2.0/irb/ruby-lex.rb:245:in `block (2 levels) in each_top_level_statement'
from /usr/local/lib/ruby/2.2.0/irb/ruby-lex.rb:231:in `loop'
from /usr/local/lib/ruby/2.2.0/irb/ruby-lex.rb:231:in `block in each_top_level_statement'
from /usr/local/lib/ruby/2.2.0/irb/ruby-lex.rb:230:in `catch'
from /usr/local/lib/ruby/2.2.0/irb/ruby-lex.rb:230:in `each_top_level_statement'
from /usr/local/lib/ruby/2.2.0/irb.rb:485:in `eval_input'
from /usr/local/lib/ruby/2.2.0/irb.rb:395:in `block in start'
from /usr/local/lib/ruby/2.2.0/irb.rb:394:in `catch'
from /usr/local/lib/ruby/2.2.0/irb.rb:394:in `start'
from /usr/local/lib/ruby/gems/2.2.0/gems/railties-4.2.0/lib/rails/commands/console.rb:110:in `start'
from /usr/local/lib/ruby/gems/2.2.0/gems/railties-4.2.0/lib/rails/commands/console.rb:9:in `start'
from /usr/local/lib/ruby/gems/2.2.0/gems/railties-4.2.0/lib/rails/commands/commands_tasks.rb:68:in `console'
from /usr/local/lib/ruby/gems/2.2.0/gems/railties-4.2.0/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
from /usr/local/lib/ruby/gems/2.2.0/gems/railties-4.2.0/lib/rails/commands.rb:17:in `<top (required)>'
from bin/rails:4:in `require'
from bin/rails:4:in `<main>'Maybe IRB bug!
On line 25 I added this tabletotal.write (hash) to be able to write it on disk and not in memory but I got the following error:
NoMethodError: undefined method `write' for {}:Hash
What is the problem here? Also how can I fix it?
Start by making it less cr*p:
def extract_data(input)
{
devicetotal: input["monitoredObjectSiteName"],
servicetotal: input["monitoredObjectPointer"],
porttotal: input["displayedName"],
queueIdtotal: input["queueId"],
discardinproftotal: input["droppedInProfOctets"].to_i,
discardoutproftotal: input["droppedOutProfOctets"].to_i,
time_unixtotal: input["timeCaptured"].to_i/1000
}.tap do |h|
h[:timeCapturedtotal] = Time.at(h[:time_unixtotal]).strftime("%B %e, %Y at %I:%M %p"),
h[:discardtotal] = h[:discardinproftotal] + h[:discardoutproftotal]
h[:device_int_stats_total] =(h[:devicetotal]+h[:porttotal]+h[:queueIdtotal]).to_s
end
end
This method is really easy to test since you just insert input and write assertions about the output.
If you want to map and apply this to the input array you would do:
data_stats.map(&:extract_data)
Your code tries to output a hash but uses the shovel operator like on a array. You need to decide if the appropiate output is an array or a hash.
I need all those variables because I use them in a html in table
format.
This won't work - the instance variables will only contain the values from the last element as they get overwritten in each iteration.
You instead need to iterate over an array of hashes or objects in the view:
<% #stats.each do |s| %>
<tr>
<td><%= s[:devicetotal] %></td>
# ...
</tr>
<% end %>
If you really want to use instance varibles you need to create a object instance for each element:
class DataStat
include ActiveModel::AttributeAssignment
attr_accessor :devicetotal, :servicetotal # ...
def self.from_import(input)
self.new(
devicetotal: input["monitoredObjectSiteName"],
servicetotal: input["monitoredObjectPointer"],
# ...
)
end
end
#stats = data_stats.map { |ds| DataStat.from_import(ds) }
You also need to deal with the issue that you´re running out of memory since you are just slop converting the whole XML document into a Ruby hash. You need to parse it with Nokogiri instead and extract what you actually need.

ruby / rails: TypeError: can't convert Symbol into Integer

I'm trying to update my Representation attributes ivpn & idirect (from a csv file via rake task but i just print here only the meat of the program) and getting the TypeError:
# in Rails Console:
representation = Representation.where(id: 977)
# => Representation_id: 977, ivnp: false, idirect: false
rows = Hash.[:ivpn => "", :idirect => "x"] # originally rows are coming from csv-file
representation.update_attributes! ivpn: rows.any?{|r| r[:ivpn].present?}, idirect: rows.any? {|r| r[:idirect].present?}
TypeError: can't convert Symbol into Integer
from (irb):42:in `[]'
from (irb):42:in `block in irb_binding'
from (irb):42:in `each'
from (irb):42:in `any?'
What I'm missing here?
try this:
representation.update_attributes! ivpn: rows.any?[{|r| r[:ivpn].present?}], idirect: rows.any? [{|r| r[:idirect].present?}]

GET method with json body

I have to consume methods from an external API provided, and one method is a GET with a json body. I'm making the connection through rails using rest-client gem that makes that job.
I know that RestClient.post accepts json:
RestClient.post "http://example.com/resource", { 'x' => 1 }.to_json, :content_type => :json, :accept => :json
And also for my case works perfectly. But if i change the .post to .get, i get this error:
ArgumentError: wrong number of arguments (3 for 2)
from /Users/toptierlabs/.rvm/gems/ruby-1.9.3-p429#rails3tutorial2ndEd/gems/rest-client-1.6.7/lib/restclient.rb:67:in `get'
from /Users/toptierlabs/Desktop/Proyectos/AppraisalLane/app/models/autoniq.rb:8:in `getCircleInventory'
from (irb):3
from /Users/toptierlabs/.rvm/gems/ruby-1.9.3-p429#rails3tutorial2ndEd/gems/railties-4.0.2/lib/rails/commands/console.rb:90:in `start'
from /Users/toptierlabs/.rvm/gems/ruby-1.9.3-p429#rails3tutorial2ndEd/gems/railties-4.0.2/lib/rails/commands/console.rb:9:in `start'
from /Users/toptierlabs/.rvm/gems/ruby-1.9.3-p429#rails3tutorial2ndEd/gems/railties-4.0.2/lib/rails/commands.rb:62:in `<top (required)>'
from bin/rails:4:in `require'
from bin/rails:4:in `<main>'
Is there any way in Rails to do a GET with a json body? Or any possible solution to translate a "get with a json body" to something else? Is not necessary to use the rest-client gem, if any one have another solution is welcome too.
Thanks!
Solved:
RestClient.get "http://example.com/resource", params: {'json' => { 'x' => 1 }.to_json},:content_type => :json, :accept => :json

Encoding::UndefinedConversionError: "\xA8" from ASCII-8BIT to UTF-8 (SFTP)

Using the Net-SFTP gem, Ruby 2 and Rails 4
I wrote code that was working in pure ruby, but copied my code over to rails and now I get:
Encoding::UndefinedConversionError: "\xA8" from ASCII-8BIT to UTF-8
What can I change in my code to get this working?
def self.get_recent_file(ftp_file, local_file)
Net::SFTP.start(Config::A_FTP[:domain], Config::A_FTP[:username], :password => Config::A_FTP[:password]) do |sftp|
sftp.download!(ftp_file, local_file)
end
end
Log
Encoding::UndefinedConversionError: "\xA8" from ASCII-8BIT to UTF-8
from /usr/local/opt/rbenv/versions/2.1.0-rc1/lib/ruby/gems/2.1.0/gems/net-sftp-2.1.2/lib/net/sftp/operations/download.rb:339:in `write'
from /usr/local/opt/rbenv/versions/2.1.0-rc1/lib/ruby/gems/2.1.0/gems/net-sftp-2.1.2/lib/net/sftp/operations/download.rb:339:in `write'
from /usr/local/opt/rbenv/versions/2.1.0-rc1/lib/ruby/gems/2.1.0/gems/net-sftp-2.1.2/lib/net/sftp/operations/download.rb:339:in `on_read'
from /usr/local/opt/rbenv/versions/2.1.0-rc1/lib/ruby/gems/2.1.0/gems/net-sftp-2.1.2/lib/net/sftp/request.rb:87:in `call'
from /usr/local/opt/rbenv/versions/2.1.0-rc1/lib/ruby/gems/2.1.0/gems/net-sftp-2.1.2/lib/net/sftp/request.rb:87:in `respond_to'
from /usr/local/opt/rbenv/versions/2.1.0-rc1/lib/ruby/gems/2.1.0/gems/net-sftp-2.1.2/lib/net/sftp/session.rb:948:in `dispatch_request'
from /usr/local/opt/rbenv/versions/2.1.0-rc1/lib/ruby/gems/2.1.0/gems/net-sftp-2.1.2/lib/net/sftp/session.rb:911:in `when_channel_polled'
from /usr/local/opt/rbenv/versions/2.1.0-rc1/lib/ruby/gems/2.1.0/gems/net-ssh-2.8.0/lib/net/ssh/connection/channel.rb:311:in `call'
from /usr/local/opt/rbenv/versions/2.1.0-rc1/lib/ruby/gems/2.1.0/gems/net-ssh-2.8.0/lib/net/ssh/connection/channel.rb:311:in `process'
from /usr/local/opt/rbenv/versions/2.1.0-rc1/lib/ruby/gems/2.1.0/gems/net-ssh-2.8.0/lib/net/ssh/connection/session.rb:222:in `block in preprocess'
from /usr/local/opt/rbenv/versions/2.1.0-rc1/lib/ruby/gems/2.1.0/gems/net-ssh-2.8.0/lib/net/ssh/connection/session.rb:222:in `each'
from /usr/local/opt/rbenv/versions/2.1.0-rc1/lib/ruby/gems/2.1.0/gems/net-ssh-2.8.0/lib/net/ssh/connection/session.rb:222:in `preprocess'
from /usr/local/opt/rbenv/versions/2.1.0-rc1/lib/ruby/gems/2.1.0/gems/net-ssh-2.8.0/lib/net/ssh/connection/session.rb:205:in `process'
from /usr/local/opt/rbenv/versions/2.1.0-rc1/lib/ruby/gems/2.1.0/gems/net-ssh-2.8.0/lib/net/ssh/connection/session.rb:169:in `block in loop'
from /usr/local/opt/rbenv/versions/2.1.0-rc1/lib/ruby/gems/2.1.0/gems/net-ssh-2.8.0/lib/net/ssh/connection/session.rb:169:in `loop'
from /usr/local/opt/rbenv/versions/2.1.0-rc1/lib/ruby/gems/2.1.0/gems/net-ssh-2.8.0/lib/net/ssh/connection/session.rb:169:in `loop'
... 13 levels...
from /usr/local/opt/rbenv/versions/2.1.0-rc1/lib/ruby/gems/2.1.0/gems/net-ssh-2.8.0/lib/net/ssh/connection/session.rb:222:in `preprocess'
from /usr/local/opt/rbenv/versions/2.1.0-rc1/lib/ruby/gems/2.1.0/gems/net-ssh-2.8.0/lib/net/ssh/connection/session.rb:205:in `process'
from /usr/local/opt/rbenv/versions/2.1.0-rc1/lib/ruby/gems/2.1.0/gems/net-ssh-2.8.0/lib/net/ssh/connection/session.rb:169:in `block in loop'
from /usr/local/opt/rbenv/versions/2.1.0-rc1/lib/ruby/gems/2.1.0/gems/net-ssh-2.8.0/lib/net/ssh/connection/session.rb:169:in `loop'
from /usr/local/opt/rbenv/versions/2.1.0-rc1/lib/ruby/gems/2.1.0/gems/net-ssh-2.8.0/lib/net/ssh/connection/session.rb:169:in `loop'
from /usr/local/opt/rbenv/versions/2.1.0-rc1/lib/ruby/gems/2.1.0/gems/net-sftp-2.1.2/lib/net/sftp/session.rb:802:in `loop'
from /usr/local/opt/rbenv/versions/2.1.0-rc1/lib/ruby/gems/2.1.0/gems/net-sftp-2.1.2/lib/net/sftp/session.rb:787:in `connect!'
from /usr/local/opt/rbenv/versions/2.1.0-rc1/lib/ruby/gems/2.1.0/gems/net-sftp-2.1.2/lib/net/sftp.rb:32:in `start'
Code referenced in log from GEM:
https://github.com/net-ssh/net-sftp/blob/master/lib/net/sftp/operations/download.rb#L339
# Called when a read from a file finishes. If the read was successful
# and returned data, this will call #download_next_chunk to read the
# next bit from the file. Otherwise the file will be closed.
def on_read(response)
entry = response.request[:entry]
if response.eof?
update_progress(:close, entry)
entry.sink.close
request = sftp.close(entry.handle, &method(:on_close))
request[:entry] = entry
elsif !response.ok?
raise "read #{entry.remote}: #{response}"
else
entry.offset += response[:data].bytesize
update_progress(:get, entry, response.request[:offset], response[:data])
entry.sink.write(response[:data]) # <~~ Line#339
download_next_chunk(entry)
end
end
This helps me:
def self.get_recent_file(ftp_file, local_file)
local_io = File.new(local_file, mode: 'w', encoding: 'ASCII-8BIT')
Net::SFTP.start(Config::A_FTP[:domain], Config::A_FTP[:username], :password => Config::A_FTP[:password]) do |sftp|
sftp.download!(ftp_file, local_io)
end
local_io.close
end
A combination of user72136's answer and the answer to this question worked for me (my remote file wasn't even ASCII):
def self.get_recent_file(ftp_file, local_file)
local_io = File.new(local_file, mode: 'wb')
Net::SFTP.start(Config::A_FTP[:domain], Config::A_FTP[:username], :password => Config::A_FTP[:password]) do |sftp|
sftp.download!(ftp_file, local_io)
end
local_io.close
end
As line#339 is showing
entry.sink.write(response[:data])
Fix it as :
entry.sink.write(response[:data].force_encoding('ASCII-8BIT').encode('UTF-8'))
Change the line -
sftp.download!(ftp_file, local_file)
to say
sftp.download!(ftp_file, local_file).to_s.encode('UTF-8', {:invalid => :replace, :undef => :replace, :replace => '?'})
This problem is being produced by how Ruby opens text-files by default after Ruby 2.0 version with UTF-8 encoding. Where you open your file you can put:
local_file = Tempfile.new(encoding: 'ascii-8bit')
#or another thing to do is to switch to binary-mode
local_file = Tempfile.new
local_file.binmode
You can also open a binary-file like this:
local_file = File.open('/tmp/local_file', 'wb')
Another solution you can do is to pass to the gem-code the filepath, instead of an open file:
def self.get_recent_file(ftp_file, local_file)
Net::SFTP.start(Config::A_FTP[:domain], Config::A_FTP[:username], :password => Config::A_FTP[:password]) do |sftp|
sftp.download!(ftp_file, local_file.path)
end
end

Resources