Dir.glob with sort issue - ruby-on-rails

As in "Alphabetize results of Dir.glob", I use sort to get file list in alphabetical order:
Dir.glob("#{options[:path]}/**/*.jpg", File::FNM_CASEFOLD).sort { |file|
dir, filename = file.match(/.+\/(.+)\/(.+)/).captures
# ---cut---
}
Without the sort it works good, but with it fails with error:
$ rake slides:import -- --user foo --path /bar/baz
(in /home/user/app_folder)
"baz/ - /bar/baz/DSC_4120.JPG - saved"
rake aborted!
ArgumentError: comparison of String with 0 failed
/home/footoo/footoo/lib/tasks/slides.rake:41:in `>'
/home/footoo/footoo/lib/tasks/slides.rake:41:in `sort'
/home/footoo/footoo/lib/tasks/slides.rake:41:in `block (2 levels) in <top (required)>'
/usr/local/rvm/gems/ruby-2.1.5/bin/ruby_executable_hooks:15:in `eval'
/usr/local/rvm/gems/ruby-2.1.5/bin/ruby_executable_hooks:15:in `<main>'
Tasks: TOP => slides:import
Any idea what's wrong ?
Full code available on Github.

When sort is given a block it expects it to return -1,0 or 1 in order to know how to sort (a custom <=> function). You need to add each after sort to get back the default sort and the intended behavior.
Dir.glob("#{options[:path]}/**/*.jpg", File::FNM_CASEFOLD).sort.each{|file|
....
}
Read the documentation here: http://ruby-doc.org/core-2.2.0/Array.html#method-i-sort

Related

ActionDispatch::ParamsParser replacement after upgrade to Rails 5

Migrating an app from Rails 4.2.9 to 5.2.1.
This is latest issue:
$ rails console
/Users/meltemi/rails/myapp/config/initializers/disable_xml_params.rb:3:in `<top (required)>': uninitialized constant ActionDispatch::ParamsParser (NameError)
from /Users/meltemi/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/railties-5.2.1/lib/rails/engine.rb:657:in `block in load_config_initializer'
from /Users/meltemi/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/activesupport-5.2.1/lib/active_support/notifications.rb:170:in `instrument'
from /Users/meltemi/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/railties-5.2.1/lib/rails/engine.rb:656:in `load_config_initializer'
The offending line of code in an initializer:
# config/initializers/disable_xml_params.rb
ActionDispatch::ParamsParser::DEFAULT_PARSERS.delete(Mime::XML)
Rails Guides says:
ActionDispatch::ParamsParser is deprecated and was removed from the middleware stack. To configure the parameter parsers use ActionDispatch::Request.parameter_parsers=. (commit, commit)
So I've tried the following:
ActionDispatch::Request.parameter_parsers.delete(Mime::XML)
But that begets more errors:
$ rails console
/Users/meltemi/rails/myapp/config/initializers/disable_xml_params.rb:3:in `<top (required)>': uninitialized constant Mime::XML (NameError)
from /Users/meltemi/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/railties-5.2.1/lib/rails/engine.rb:657:in `block in load_config_initializer'
from /Users/meltemi/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/activesupport-5.2.1/lib/active_support/notifications.rb:170:in `instrument'
from /Users/meltemi/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/railties-5.2.1/lib/rails/engine.rb:656:in `load_config_initializer'
Is there a better way to call .delete on that object?
You have to grab the existing values from parameter_parsers, modify it to suit your needs, then reset the values to your modified values. From the ActionDispatch::Http::Parameters documentation:
parameter_parsers=(parsers)
Configure the parameter parser for a given MIME type.
It accepts a hash where the key is the symbol of the MIME type and the value is a proc.
original_parsers = ActionDispatch::Request.parameter_parsers
xml_parser = -> (raw_post) { Hash.from_xml(raw_post) || {} }
new_parsers = original_parsers.merge(xml: xml_parser)
ActionDispatch::Request.parameter_parsers = new_parsers
In your specific case, you should look at the parsers in original_parsers to see if there is anything to delete. On a simple Rails 5 app that I have handy to look at, the only values I have are:
=> {
:json => #<Proc:0x00007fe818fc6fb8#/Users/foo/.rvm/gems/ruby-2.6.0-preview2/gems/actionpack-5.2.1/lib/action_dispatch/http/parameters.rb:11 (lambda)>
}
Your app's configuration is likely different, but to answer your question about how to delete a value, this simple version should work:
ActionDispatch::Request.parameter_parsers = ActionDispatch::Request.parameter_parsers.except(:json)
You may find additional useful information in this answer.

YAML Parsing Issue in Rails

I have an issue on Elastic Beanstalk deployment which is:
YAML syntax error occurred while parsing /var/app/ondeck/config/database.yml. Please note that YAML must be consistently indented using spaces. Tabs are not allowed. Error: (<unknown>): found character that cannot start any token while scanning for the next token at line 2 column 1 /var/app/ondeck/config/environment.rb:5:in `<top (required)>' /opt/rubies/ruby-2.4.2/bin/bundle:23:in `load' /opt/rubies/ruby-2.4.2/bin/bundle:23:in `<main>'
Caused by: Psych::SyntaxError: (<unknown>): found character that cannot start any token while scanning for the next token at line 2 column 1 /var/app/ondeck/config/environment.rb:5:in `<top (required)>' /opt/rubies/ruby-2.4.2/bin/bundle:23:in `load' /opt/rubies/ruby-2.4.2/bin/bundle:23:in `<main>' Tasks: TOP => environment (See full trace by running task with --trace).
As what I have read, this is because YAML forbids using tabs, instead it uses spaces.
The problem is that I manually checked every YAML file for tabs, and never found one. I think I missed something so my question is: is there any script that can go through my entire source code replacing tabs with 2 spaces in every YAML file?
It’s ruby after all: it’s easier and faster to write the script rather than ask questions on SO and google for it.
Dir['*/**/*.yml'].each do |f|
File.write(f, File.read(f).gsub(/\t/, ' '))
end

How to display rspec errors faster?

My rspec test suite is slow. It takes about half a decade to run all the tests. While it's running, I see only that tests are failing.
.......................................................................
.......FFFFFFFFFFFFFFF....F..........FFFFFFFFF.........................
................FFFFFFFFFFFFFFF.....................FF.................
..........................FFF..........................................
.............FFFFFFFFFFFFFFFFFFFFFF....................................
................................................................FFFF...
.......FFFFFFFFF..........................
Then, after staring at this for a few years, I finally get a listing of what is wrong.
Failures:
172481) Foobar should barfoo the barbaz while quux is set to narf
Failure/Error: before { click_link "Enable narf" }
ArgumentError:
wrong number of arguments (0 for 1)
# ./app/helpers/foobar_helper.rb:22:in `gobble'
# ./app/controllers/barbaz_controller.rb:18:in `omgwtf'
# (eval):2:in `click_link'
# ./spec/requests/metasyntactic_spec.rb:43:in `block (5 levels) in <top (required)>'
Is there a way to tell rspec it should display the errors directly - while running the test suite?
You can use the fuubar format, see the doc here : https://github.com/jeffkreeftmeijer/fuubar/

ArgumentError: wrong number of arguments (0 for 1)

I am trying to test insert a row into sqlite3 db, for the Rails Tutorial in Chapter 7. I have gone over the code many times and it looks correct, however in the console I am getting the following error. Any suggestions?
User.create(name=>"test user",:email=>"testuser#example.com",:password=>"foobar",:password_confirmation=>"foobar")
ArgumentError: wrong number of arguments (0 for 1)
from /Library/Ruby/Gems/1.8/gems/activerecord-3.0.3/lib/active_record/base.rb:442:in maximum'
from /Library/Ruby/Gems/1.8/gems/activerecord-3.0.3/lib/active_record/base.rb:442:insend'
from /Library/Ruby/Gems/1.8/gems/activerecord-3.0.3/lib/active_record/base.rb:442:in maximum'
from /Users/gabemcmillan/rails_projects/sample_app/app/models/user.rb:10
from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:454:inload'
from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:454:in load_file'
from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:596:innew_constants_in'
from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:453:in load_file'
from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:340:inrequire_or_load'
from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:491:in load_missing_constant'
from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:183:inconst_missing'
from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:181:in each'
from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:181:inconst_missing'
from (irb):8
It should be User.create(:name... (with a colon before name), not User.create(name...

When working with gems in Rails, what does 'cannot remove Object::ClassMethods' stem from?

Frequently I have run into a problem when installing gems that provides a problem like:
Does anyone know what this stems from? I've seen in it several different cases, yet still haven't learned what exactly is causing it.
$ sudo rake gems:install --trace
(in /u/app/releases/20100213003957)
** Invoke gems:install (first_time)
** Invoke gems:base (first_time)
** Execute gems:base
** Invoke environment (first_time)
** Execute environment
rake aborted!
cannot remove Object::ClassMethods
/u/app/releases/20100213003957/vendor/rails/activesupport/lib/active_support/dependencies.rb:603:in `remove_const'
/u/app/releases/20100213003957/vendor/rails/activesupport/lib/active_support/dependencies.rb:603:in `remove_constant'
/u/app/releases/20100213003957/vendor/rails/activesupport/lib/active_support/dependencies.rb:603:in `instance_eval'
/u/app/releases/20100213003957/vendor/rails/activesupport/lib/active_support/dependencies.rb:603:in `remove_constant'
/u/app/releases/20100213003957/vendor/rails/activesupport/lib/active_support/dependencies.rb:549:in `new_constants_in'
/u/app/releases/20100213003957/vendor/rails/activesupport/lib/active_support/dependencies.rb:549:in `each'
/u/app/releases/20100213003957/vendor/rails/activesupport/lib/active_support/dependencies.rb:549:in `new_constants_in'
/u/app/releases/20100213003957/vendor/rails/activesupport/lib/active_support/dependencies.rb:156:in `require'
/u/app/releases/20100213003957/vendor/rails/railties/lib/tasks/misc.rake:4
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:617:in `call'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:617:in `execute'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:612:in `each'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:612:in `execute'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:578:in `invoke_with_call_chain'
/usr/lib64/ruby/1.8/monitor.rb:242:in `synchronize'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:571:in `invoke_with_call_chain'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:564:in `invoke'
/u/app/releases/20100213003957/vendor/rails/railties/lib/tasks/gems.rake:17
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:617:in `call'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:617:in `execute'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:612:in `each'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:612:in `execute'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:578:in `invoke_with_call_chain'
/usr/lib64/ruby/1.8/monitor.rb:242:in `synchronize'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:571:in `invoke_with_call_chain'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:588:in `invoke_prerequisites'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:585:in `each'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:585:in `invoke_prerequisites'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:577:in `invoke_with_call_chain'
/usr/lib64/ruby/1.8/monitor.rb:242:in `synchronize'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:571:in `invoke_with_call_chain'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:564:in `invoke'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:2027:in `invoke_task'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:2005:in `top_level'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:2005:in `each'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:2005:in `top_level'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:2044:in `standard_exception_handling'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:1999:in `top_level'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:1977:in `run'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:2044:in `standard_exception_handling'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/lib/rake.rb:1974:in `run'
/usr/lib64/ruby/gems/1.8/gems/rake-0.8.4/bin/rake:31
/usr/bin/rake:19:in `load'
/usr/bin/rake:19
I believe I've found a practical non-intrusive method to get at the root of the problem. It works for me (Rails 2.3) :
As it happens Exception#blame_file! is invoked at some point in spite of the fact that it will fail and cause a new error, thus masking the original error.
So, open your FIRST initializer and add,
class Exception
def blame_file!( file )
puts "CULPRIT >> '#{file.to_s}' # #{self.to_s}"
end
end
You'll get both the incriminated file and the original error message. That should be enough to pinpoint your problem.
Don't forget to remove the Exception initializer snippet.
The cause of this error is a double exception. Usually something in your code is crashing, which raises an initial exception. Then Rails' custom require attempts to keep the namespace clean by removing partially defined constants, which is the purpose of the new_constants_in method. The problem is that new_constants_in is not properly handling some particular construction somewhere within the code, I suspect due to mishandling of module namespaces or something (because ClassMethods is probably inside some module other than Object). In any case, I have not traced the error back to a Rails component or anything else, because frankly it's not worth the effort.
The solution (short of proposing something a little less invasive to Rails core) is a quick hack to figure out what raised the original exception. All you need to do is go to where Dependencies.new_constants_in is called and comment it out (there are a few places where this could be). So for example:
def require(file, *extras) #:nodoc:
if Dependencies.load?
Dependencies.new_constants_in(Object) { super }
else
super
end
rescue Exception => exception # errors from required file
exception.blame_file! file
raise
end
Comment out the new_constants_in stuff:
def require(file, *extras) #:nodoc:
# if Dependencies.load?
# Dependencies.new_constants_in(Object) { super }
# else
super
# end
#rescue Exception => exception # errors from required file
# exception.blame_file! file
# raise
end
Then you'll see your error straight away.
I just came across this problem again. After some debugging I came to this conclusion: this weird error means that Rails has some troubles with requiring some particular library. The problem is that Rails doesn't tell us which library causes the problem. So, the first step you have to do is this:
Open this file (or the appropriate file in your installation):
/u/app/releases/20100213003957/vendor/rails/activesupport/lib/active_support/dependencies.rb
and edit the load_with_new_constant_marking method so it looks like this:
def load_with_new_constant_marking(file, *extras) #:nodoc:
if Dependencies.load?
Dependencies.new_constants_in(Object) { load_without_new_constant_marking(file, *extras) }
else
load_without_new_constant_marking(file, *extras)
end
rescue Exception => exception # errors from loading file
puts "FAILS HERE: " + file
exception.blame_file! file
raise
end
From now on, when running your application or a rake task, instead of just telling you that it "cannot remove Object::ClassMethods" Rails will tell you which file causes the problem (just look for the "FAILS HERE" statement). (Btw. I suppose this is what the exception.blame_file! method should be doing, but it obviously doesn't work that way.)
After you have located the file which causes the problem, you can dig into that particular chunk and use some exception blocks to get to the core of the problem.
Hope this helps.
I also started catching this bizarre error today -- traced it back to an out-of-date mysql gem .
I'd just switched from using the Mac MySQL package (the one that comes with a PrefPane) to a Homebrew-compiled version and the old /usr/local/mysql was lingering in my PATH
Deleting that directory (and other traces of the old MySQL) and then re-bundling my app solved it!
I ran into this issue, and tried each of the above solutions, but to no avail.
In my case, the problem was that I had accidentally included ActionView::Helpers::TextHelper and ActionView::Helpers::NumberHelper at the top of a file (thereby including them into the root Object class), this worked OK in Rails 3.0.0.rc, but raised the "cannot remove Object::ClassMethods" in Rails 3.0.1, and once raised, the app remained stuck until the server was restarted.
This started happening with me, but only after I included the delayed_job gem in my bundle. Like Eric above, I included ActionView::Helpers::TextHelper and ActionView::Helpers::NumberHelper at the top of a controller, but the funny thing is that I had no problems whatsoever until I started using delayed_job. I've no idea what's going on, I just removed the includes and the problem seems to have disappeared.

Resources