Type restriction for Volt Framework model throws error - voltrb

I would like to set type restrictions for a Volt Model like so
class EventItemBlock < Volt::Model
:name, String
:items, Volt::ArrayModel
end
When I save the file, Volt throws an error behind-the-scenes but does not crash. The relevant lines are the first seven (7), which state that the comma is a syntax error.
In the Volt Framework documentation, the comma is documented as proper syntax (http://docs.voltframework.com/en/docs/models.html). Removing the comma does not resolve errors--only removing the type restriction does.
[ERROR] #<SyntaxError: /home/jg/ModelTest/app/main/models/event_item_block.rb:2: syntax error, unexpected ',', expecting keyword_end
:name, String
^
/home/jg/ModelTest/app/main/models/event_item_block.rb:3: syntax error, unexpected ',', expecting keyword_end
:items, Volt::ArrayModel
^>
/home/jg/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/volt-0.9.4/lib/volt/server/rack/component_paths.rb:67:in `require'
/home/jg/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/volt-0.9.4/lib/volt/server/rack/component_paths.rb:67:in `block (2 levels) in require_in_components'
/home/jg/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/volt-0.9.4/lib/volt/server/rack/component_paths.rb:65:in `each'
/home/jg/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/volt-0.9.4/lib/volt/server/rack/component_paths.rb:65:in `block in require_in_components'
/home/jg/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/volt-0.9.4/lib/volt/server/rack/component_paths.rb:31:in `block in app_folders'
/home/jg/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/volt-0.9.4/lib/volt/server/rack/component_paths.rb:30:in `each'
/home/jg/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/volt-0.9.4/lib/volt/server/rack/component_paths.rb:30:in `app_folders'
/home/jg/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/volt-0.9.4/lib/volt/server/rack/component_paths.rb:61:in `require_in_components'
/home/jg/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/volt-0.9.4/lib/volt/volt/server_setup/app.rb:16:in `setup_paths'
/home/jg/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/volt-0.9.4/lib/volt/volt/app.rb:74:in `initialize'
/home/jg/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/volt-0.9.4/lib/volt/boot.rb:21:in `new'
/home/jg/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/volt-0.9.4/lib/volt/boot.rb:21:in `boot'
/home/jg/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/volt-0.9.4/lib/volt/server.rb:44:in `boot_volt'
/home/jg/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/volt-0.9.4/lib/volt/server/forking_server.rb:73:in `start_child'
/home/jg/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/volt-0.9.4/lib/volt/server/forking_server.rb:229:in `block in reload'
/home/jg/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/volt-0.9.4/lib/volt/utils/read_write_lock.rb:65:in `with_write_lock'
/home/jg/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/volt-0.9.4/lib/volt/server/forking_server.rb:227:in `reload'
/home/jg/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/volt-0.9.4/lib/volt/server/forking_server.rb:239:in `block (2 levels) in start_change_listener'

Ok, two things going on here. 1) your syntax if wrong. You need to do:
field :something, SomeClass
Second, you can't currently restrict to Volt::ArrayModel (yet, on the todo list)

Related

Ruby curly bracket block syntax is not working while do...end works

I am using this gem. When I use the following syntax, it works fine:
every :day do
rake 'billing:daily'
end
However, when I use the following syntax, the gem is giving me syntax error:
every :day { rake 'billing:daily' }
Output:
~/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/whenever-0.10.0/lib/whenever/job_list.rb:25:in `instance_eval': config/schedule.rb:26: syntax error, unexpected '{', expecting end-of-input (SyntaxError)
every :day { rake 'billing:daily' }
^
from ~/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/whenever-0.10.0/lib/whenever/job_list.rb:25:in `initialize'
from ~/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/whenever-0.10.0/lib/whenever.rb:12:in `new'
from ~/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/whenever-0.10.0/lib/whenever.rb:12:in `cron'
from ~/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/whenever-0.10.0/lib/whenever/command_line.rb:42:in `run'
from ~/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/whenever-0.10.0/lib/whenever/command_line.rb:6:in `execute'
from ~/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/whenever-0.10.0/bin/whenever:44:in `<top (required)>'
from ~/.rbenv/versions/2.4.3/bin/whenever:23:in `load'
from ~/.rbenv/versions/2.4.3/bin/whenever:23:in `<main>'
Aren't both the same thing? Why is the former working but not the latter?
It's a parsing/precedence issue. Braces try to bind to the nearest token, which is :day in this case, but you want it to bind to every(). You have to write every(:day) { rake 'billing:daily' } to explicitly bind it to the correct token.
In ruby 2.4.2 was introduced regression in block parsing. While in ruby 2.4.1 you could use:
every :day { rake 'billing:daily' }
in ruby 2.4.2 you have to wrap the function parameters in brackets if you call it with a block otherwise you will get a SyntaxError:
every(:day) { rake 'billing:daily' }

Ruby Undefined method downcase

I'm getting an exception in the following piece of code. Can someone please tell me what I'm doing wrong, and how I can prevent it?
def self.find_by_data(data = {})
where(name_canonical: data['name'].downcase.gsub(/\s+/, ''),
fuel: data['fuel'],
trim_canonical: data['trim'].downcase.gsub(/\s+/, ''),
year: data['year']).first
end
Exception:
/Users/charlie/Documents/WIP/projectx/ar_models.rb:35:in `find_by_data': undefined method `downcase' for nil:NilClass (NoMethodError)ooooooooooooooooooooooooo| ETA: 0:00:00
from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/relation/delegation.rb:36:in `block in find_by_data'
from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/associations/collection_proxy.rb:845:in `block in scoping'
from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/relation.rb:270:in `scoping'
from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/associations/collection_proxy.rb:845:in `scoping'
from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/relation/delegation.rb:36:in `find_by_data'
from /Users/charlie/Documents/WIP/projectx/ar_models.rb:132:in `create_or_assign_existing'
from /Users/charlie/Documents/WIP/projectx/app.rb:230:in `block (2 levels) in work'
from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:294:in `with_connection'
from /Users/charlie/Documents/WIP/projectx/app.rb:80:in `block in work'
from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/parallel-0.6.3/lib/parallel.rb:319:in `call'
from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/parallel-0.6.3/lib/parallel.rb:319:in `call_with_index'
from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/parallel-0.6.3/lib/parallel.rb:179:in `block (3 levels) in work_in_threads'
from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/parallel-0.6.3/lib/parallel.rb:326:in `with_instrumentation'
from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/parallel-0.6.3/lib/parallel.rb:177:in `block (2 levels) in work_in_threads'
from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/parallel-0.6.3/lib/parallel.rb:171:in `loop'
from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/parallel-0.6.3/lib/parallel.rb:171:in `block in work_in_threads'
from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/parallel-0.6.3/lib/parallel.rb:62:in `block (2 levels) in in_threads'
When you see "undefined method ... for nil:NilClass" it means you have a nil value you're trying to call the method on.
In this case, something like data['name'] is not defined.
To make this more bullet-proof:
data['name'].to_s.downcase.gsub(/\s+/, '')
This converts everything to string to start with. nil.to_s is an empty string by default, so it's safe.
Use ternary oprators perhaps:
def self.find_by_data(data = {})
where(name_canonical: data['name'] == nil ? '' : data['name'].downcase.gsub(/\s+/, ''),
fuel: data['fuel'],
trim_canonical: data['trim'] == nil ? '' : data['name'].downcase.gsub(/\s+/, ''),
year: data['year']).first
end
Your
data['name']
or
data['trim']
is a nil.
Check your input data.

Cannot read span elements

Hi since I did gem install watir watir-classic my scripts are not reading anymore the span elements. Can you please help me to fix this problem
here my example
Source
Rented
<SPAN class="displayData" style="padding-left:2px; width: 15;"><span name="tab4RateInfoForm.vehicleGroup"/>F</span></SPAN>
My code
carGroup=browser.span(:name => 'tab4RateInfoForm.vehicleGroup').text
Error message
C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-classic-3.3.0/lib/watir-classic/locator.rb:79:in `rescue in match?': name is an unknown way of finding a <span> element (tab4RateInfoForm.vehicleGroup) (Watir::Exception::MissingWayOfFindingObjectException)
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-classic-3.3.0/lib/watir-classic/locator.rb:76:in `match?'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-classic-3.3.0/lib/watir-classic/locator.rb:62:in `block in match_with_specifiers?'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-classic-3.3.0/lib/watir-classic/locator.rb:59:in `each'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-classic-3.3.0/lib/watir-classic/locator.rb:59:in `all?'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-classic-3.3.0/lib/watir-classic/locator.rb:59:in `match_with_specifiers?'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-classic-3.3.0/lib/watir-classic/locator.rb:22:in `block (2 levels) in each'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-classic-3.3.0/lib/watir-classic/locator.rb:140:in `block in each_element'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-classic-3.3.0/lib/watir-classic/locator.rb:139:in `each'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-classic-3.3.0/lib/watir-classic/locator.rb:139:in `each_element'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-classic-3.3.0/lib/watir-classic/locator.rb:21:in `block in each'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-classic-3.3.0/lib/watir-classic/locator.rb:20:in `each'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-classic-3.3.0/lib/watir-classic/locator.rb:20:in `each'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-classic-3.3.0/lib/watir-classic/locator.rb:150:in `locate'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-classic-3.3.0/lib/watir-classic/element.rb:33:in `locate'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-classic-3.3.0/lib/watir-classic/element.rb:63:in `assert_exists'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-classic-3.3.0/lib/watir-classic/element.rb:132:in `text'
Solution 1: Use css locator
You will have to use a css-locator (or xpath):
carGroup = browser.span(:css, 'span[name="tab4RateInfoForm.vehicleGroup"]').text
Solution 2: Monkey patch
Alternatively, if you have a lot of legacy scripts that use the name attribute, you can monkey patch Watir to have the name method for all elements (or specific element if desired).
Add the following to wherever you require watir:
Watir::IE.new(true)
module Watir
class Element
def name
return self.attribute_value('name')
end
end
end
Your original method should now work.
Looks like span elements can no longer be accessed via name attribute.
Try this (use generic element instead of span):
carGroup=browser.element(:name => 'tab4RateInfoForm.vehicleGroup').text

Sequel gem: Handling invalid date values gracefully

I'm a ruby noob and I'm trying to process some blog posts using Sequel and the data_objects adapter:
DB = Sequel.connect('do:mysql://user:pass#localhost/database')
db[posts_query].each do |post|
puts post
end
But I get Sequel::InvalidValue exception, complaining about the date column:
/usr/lib/ruby/1.9.1/time.rb:202:in `local': ArgumentError: argument out of range (Sequel::InvalidValue)
from /usr/lib/ruby/1.9.1/time.rb:202:in `make_time'
from /usr/lib/ruby/1.9.1/time.rb:271:in `parse'
from /var/lib/gems/1.9.1/gems/sequel-3.42.0/lib/sequel/core.rb:295:in `string_to_datetime'
I tried to catch the exception:
begin
db[posts_query].each do |post|
puts post
end
rescue Sequel::InvalidValue => e
puts e.inspect
end
but that doesn't help much.
How can I find out which row has the incorrect value?
Also, is there a way to do this iteration, such that I can catch the exception but continue to loop over the remaining rows?
Update:
I switched to the mysql2 adapter and now I can at least see the invalid date:
/var/lib/gems/1.9.1/gems/sequel-3.42.0/lib/sequel/adapters/mysql2.rb:154:in `each': Mysql2::Error: Invalid date: 2008-04-00 00:00:15 (Sequel::DatabaseError)
from /var/lib/gems/1.9.1/gems/sequel-3.42.0/lib/sequel/adapters/mysql2.rb:154:in `block in fetch_rows'
from /var/lib/gems/1.9.1/gems/sequel-3.42.0/lib/sequel/adapters/mysql2.rb:89:in `_execute'
from /var/lib/gems/1.9.1/gems/sequel-3.42.0/lib/sequel/adapters/shared/mysql_prepared_statements.rb:34:in `block in execute'
from /var/lib/gems/1.9.1/gems/sequel-3.42.0/lib/sequel/database/connecting.rb:236:in `block in synchronize'
from /var/lib/gems/1.9.1/gems/sequel-3.42.0/lib/sequel/connection_pool/threaded.rb:104:in `hold'
from /var/lib/gems/1.9.1/gems/sequel-3.42.0/lib/sequel/database/connecting.rb:236:in `synchronize'
from /var/lib/gems/1.9.1/gems/sequel-3.42.0/lib/sequel/adapters/shared/mysql_prepared_statements.rb:34:in `execute'
from /var/lib/gems/1.9.1/gems/sequel-3.42.0/lib/sequel/dataset/actions.rb:778:in `execute'
from /var/lib/gems/1.9.1/gems/sequel-3.42.0/lib/sequel/adapters/mysql2.rb:171:in `execute'
from /var/lib/gems/1.9.1/gems/sequel-3.42.0/lib/sequel/adapters/mysql2.rb:140:in `fetch_rows'
from /var/lib/gems/1.9.1/gems/sequel-3.42.0/lib/sequel/dataset/actions.rb:154:in `each'
from wordpress_importer.rb:112:in `process'
from wordpress_importer.rb:308:in `<main>'
Can you post more of the backtrace? You need to see what is calling string_to_datetime.
Also, I would recommend against using the do/mysql adapter unless you have specific needs that require it. Use the mysql or mysql2 adapter instead. If the error is being caused by bogus datetimes in your MySQL database, then you may want to use the mysql2 adapter or use the mysql adapter and set DB.convert_invalid_date_time = nil.

Can I use parameter-less functions in Ruby 1.9.x?

So I'm working through the Ruby Koans, and I've encountered an issue that I think is specific to ruby 1.9.x.
def test_calling_global_methods_without_parentheses
result = my_global_method 2, 3
assert_equal 5, result
end
I get this:
james#tristan:~/code/ruby_projects/ruby_koans$ rake
(in /home/james/code/ruby_projects/ruby_koans)
cd koans
/home/james/.rvm/rubies/ruby-1.9.2-p180/bin/ruby path_to_enlightenment.rb
/home/james/code/ruby_projects/ruby_koans/koans/about_methods.rb:21:in `eval': (eval):1: syntax error, unexpected tINTEGER, expecting keyword_do or '{' or '(' (SyntaxError)
assert_equal 5, my_global_method 2, 3
^
from /home/james/code/ruby_projects/ruby_koans/koans/about_methods.rb:21:in `test_sometimes_missing_parentheses_are_ambiguous'
from /home/james/code/ruby_projects/ruby_koans/koans/edgecase.rb:377:in `meditate'
from /home/james/code/ruby_projects/ruby_koans/koans/edgecase.rb:449:in `block in walk'
from /home/james/code/ruby_projects/ruby_koans/koans/edgecase.rb:460:in `block (3 levels) in each_step'
from /home/james/code/ruby_projects/ruby_koans/koans/edgecase.rb:458:in `each'
from /home/james/code/ruby_projects/ruby_koans/koans/edgecase.rb:458:in `block (2 levels) in each_step'
from /home/james/code/ruby_projects/ruby_koans/koans/edgecase.rb:457:in `each'
from /home/james/code/ruby_projects/ruby_koans/koans/edgecase.rb:457:in `each_with_index'
from /home/james/code/ruby_projects/ruby_koans/koans/edgecase.rb:457:in `block in each_step'
from /home/james/code/ruby_projects/ruby_koans/koans/edgecase.rb:455:in `catch'
from /home/james/code/ruby_projects/ruby_koans/koans/edgecase.rb:455:in `each_step'
from /home/james/code/ruby_projects/ruby_koans/koans/edgecase.rb:448:in `walk'
from /home/james/code/ruby_projects/ruby_koans/koans/edgecase.rb:470:in `block in <top (required)>'
rake aborted!
Command failed with status (1): [/home/james/.rvm/rubies/ruby-1.9.2-p180/bi...]
/home/james/code/ruby_projects/ruby_koans/Rakefile:86:in `block in <top (required)>'
(See full trace by running task with --trace)
james#tristan:~/code/ruby_projects/ruby_koans$
I've looked at a few different repositories on GitHub that claim to have completed the Koans recently (In the past two months), and I've only seen the answer (First code snippet) that I used. So, is it something with my code, my Ruby install or something else?
The error you're getting is not from the code you listed; it's from the code underneath it. See line 20 of the related file. The notes say:
NOTE: We are Using eval below because the example code considered to be syntactically invalid
I don't know why, but the code is being evaluated like this:
def test_calling_global_methods_without_parentheses
assert_equal 5, my_global_method 2, 3
end
The problem is that this is ambiguos, can mean assert_equal(5, my_global_method(2, 3)) or assert_equal(5, my_global_method(2), 3). In this specific case, you have to use parentheses.
Don't forget to remove the space between the method call and the first parameter.
Do this
eval "assert_equal 5, my_global_method(2,3)"
and not
eval "assert_equal 5, my_global_method (2,3)" #beware of the space!

Resources