o.respond_to?(:empty?) and o.empty? Fails with: "undefined method `empty?`" - ruby-on-rails

so how is that possible?
I have a Module, that puts a Ruby Object at the end of the renderd page in a nice structured HTML. So i recurse through the given object and build the HTML output. The following is an excerpt of the code where the error is thrown.
EDIT:(had a copy error in code)
o=some object
nicer=if o.respond_to?(:empty?) and o.empty?
add_class='empty'
'empty ' + class_name
else
case o
when TrueClass then
"TRUE"
when FalseClass then
"FALSE"
when Array
#some more when's
the error thrown: undefined method 'empty?' for #Journey::Routes:0x123456
the object (o) it self is ActionDispatch::Routing::RouteSet
again: how is that possible?
EDIT: Stack: (there is the bad one ...)
actionpack (3.2.13) lib/action_dispatch/routing/route_set.rb:366:in `empty?'
lib/tech_draw.rb:90:in `format_nice'
lib/tech_draw.rb:101:in `block in format_nice'
lib/tech_draw.rb:100:in `each'
lib/tech_draw.rb:100:in `map'
lib/tech_draw.rb:100:in `format_nice'
lib/tech_draw.rb:124:in `block in format_nice'
lib/tech_draw.rb:123:in `map'
lib/tech_draw.rb:123:in `format_nice'
lib/tech_draw.rb:13:in `block in say'
lib/tech_draw.rb:13:in `map'
lib/tech_draw.rb:13:in `say'
lib/tech_draw.rb:13:in `map'
lib/tech_draw.rb:6:in `say'
app/controllers/home_controller.rb:131:in `any_page'
actionpack (3.2.13) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
...

How is that possible? Easy:
class Thing
def respond_to? *args
true
end
end
o = Thing.new
o.respond_to?(:empty?) and o.empty?
# => NoMethodError: undefined method `empty?' for #<Thing:0x00000100ae2558>
Although why is it happening in this case is another matter.
ActionDispatch::Routing::RouteSet#empty? appears to call empty? on routes object. Assuming this object is an instance of Journey::Routes that would explain the error, as Journey::Routes doesn’t have an empty? method. (In current Rails versions Journey is part of Rails itself, but in Rails 3.2 it is separate).
I don’t why this is happening in your case though.

Related

Ruby NoMethodError: undefined method `messages' for []:Array

Since google did not help me in my quest to figure this out, I figured I would share it for anyone else that runs into this problem:
When attempting to save a model, I get
NoMethodError: undefined method `messages' for []:Array
0: /.../active_record/autosave_association.rb:491:in `_ensure_no_duplicate_errors'
1: /.../active_support/callbacks.rb:413:in `block in make_lambda'
2: /.../active_support/callbacks.rb:246:in `block in halting'
3: /.../active_support/callbacks.rb:511:in `block in invoke_after'
4: /.../active_support/callbacks.rb:511:in `each'
5: /.../active_support/callbacks.rb:511:in `invoke_after'
6: /.../active_support/callbacks.rb:132:in `run_callbacks'
7: /.../active_support/callbacks.rb:825:in `_run_validation_callbacks'
8: /.../active_model/validations/callbacks.rb:110:in `run_validations!'
9: /.../active_model/validations.rb:335:in `valid?'
Example model:
class Foo < ActiveRecord::Base
def do_stuff
#errors = []
#errors << 'Bad stuff' if self.bar > 4
#errors
end
end
Example code:
foo = Foo.first
foo.do_stuff
foo.save # or foo.valid?, etc.
The Cause
The cause of this error message is that the Foo class creates an instance level #errors variable.
ActiveRecord keeps track of database errors in a model's errors variable. When you try to validate a model, it checks for error messages in this variable.
The Solution
Change #errors to a different name (e.g. #foo_errors).

Undefined method 'detect' for :"Model#property":Symbol. Bad self-referential Neo4j model definitions?

When running unit tests I get the following error for some of my tests:
6) Error:
test_name_can't_be_nil(NodeTest):
NoMethodError: undefined method `detect' for :"Node#children":Symbol
/Users/dave/.rvm/gems/jruby-1.6.7.2/gems/activemodel-3.1.4/lib/active_model/naming.rb:85:in `model_name'
/Users/dave/.rvm/gems/jruby-1.6.7.2/gems/activemodel-3.1.4/lib/active_model/errors.rb:315:in `generate_message'
org/jruby/RubyArray.java:2339:in `collect'
/Users/dave/.rvm/gems/jruby-1.6.7.2/gems/activemodel-3.1.4/lib/active_model/errors.rb:314:in `generate_message'
/Users/dave/.rvm/gems/jruby-1.6.7.2/gems/activemodel-3.1.4/lib/active_model/errors.rb:235:in `add'
/Users/dave/.rvm/gems/jruby-1.6.7.2/gems/activemodel-3.1.4/lib/active_model/errors.rb:256:in `add_on_blank'
org/jruby/RubyArray.java:1615:in `each'
/Users/dave/.rvm/gems/jruby-1.6.7.2/gems/activemodel-3.1.4/lib/active_model/errors.rb:254:in `add_on_blank'
/Users/dave/.rvm/gems/jruby-1.6.7.2/gems/activemodel-3.1.4/lib/active_model/validations/presence.rb:9:in `validate'
org/jruby/RubyBasicObject.java:1704:in `__send__'
org/jruby/RubyKernel.java:2101:in `send'
/Users/dave/.rvm/gems/jruby-1.6.7.2/gems/activesupport-3.1.4/lib/active_support/callbacks.rb:306:in `_callback_before_47'
/Users/dave/.rvm/gems/jruby-1.6.7.2/gems/activesupport-3.1.4/lib/active_support/callbacks.rb:410:in `_run_validate_callbacks'
org/jruby/RubyBasicObject.java:1698:in `__send__'
org/jruby/RubyKernel.java:2097:in `send'
/Users/dave/.rvm/gems/jruby-1.6.7.2/gems/activesupport-3.1.4/lib/active_support/callbacks.rb:81:in `run_callbacks'
/Users/dave/.rvm/gems/jruby-1.6.7.2/gems/activemodel-3.1.4/lib/active_model/validations.rb:212:in `run_validations!'
/Users/dave/.rvm/gems/jruby-1.6.7.2/gems/activemodel-3.1.4/lib/active_model/validations.rb:179:in `valid?'
/Users/dave/.rvm/gems/jruby-1.6.7.2/gems/neo4j-2.0.1-java/lib/neo4j/rails/validations.rb:29:in `valid?'
/Users/dave/.rvm/gems/jruby-1.6.7.2/gems/neo4j-2.0.1-java/lib/neo4j/rails/callbacks.rb:26:in `valid_with_callbacks?'
/Users/dave/.rvm/gems/jruby-1.6.7.2/gems/activesupport-3.1.4/lib/active_support/callbacks.rb:405:in `_run_validation_callbacks'
/Users/dave/.rvm/gems/jruby-1.6.7.2/gems/neo4j-2.0.1-java/lib/neo4j/rails/callbacks.rb:26:in `valid_with_callbacks?'
/Users/dave/Projects/myapp/test/test_helper.rb:11:in `assert_presence'
/Users/dave/Projects/myapp/test/unit/node_test.rb:9:in `test_name_can't_be_nil'
org/jruby/RubyBasicObject.java:1698:in `__send__'
The offending test in question is:
class NodeTest < ActiveSupport::TestCase
def assert_presence( model, field)
model.send( (field.to_s + '='), nil )
model.valid?
assert_match /can not be blank/, model.errors[field].join,
"Presence error for #{field} not found on #model.class"
end
def setup
#node = FactoryGirl.build :node
end
test "name can't be nil" do
assert_presence #node, :name
end
....
end
Where Nodes are defined in the model as:
class Node < Neo4j::Rails::Model
include Neo4j::NodeMixin
property :name, type: String, index: :exact
property :description, type: String
has_one(:creator).from(User, :created_nodes)
has_n(:children).to(Node) ## <--- Suspected difficult line
has_n(:parents).from(Node, :children) ## <--- Suspected difficult line
has_n(:capable_users).from(User, :capabilities)
# The following has the Class commented out because this somehow triggers
# an error from the 'has_n(:children).to(Node)' line
has_n(:challenges) #.to(Challenge)
....
end
Basically, the server can run fine, but will crash anytime I try to call valid? on a Node (not other models). Does anyone know why this might be happening?
The problem was my choice of attributes, namely parents (and maybe children).
I took a look at the source in active model where the error was occurring (here), and saw this:
def model_name
#_model_name ||= begin
namespace = self.parents.detect { |n| n.respond_to?(:_railtie) } # <--- this line
ActiveModel::Name.new(self, namespace)
end
end
As you can see, parents appears to be in use. I changed the names and the validations, saving, etc, now works.

Rails 3.2 Uniqueness validation raises undefined method 'zero?' for nil:Nilclass

I am using Rails 3.2.0.
I have a simple model as show below
class Favorite < ActiveRecord::Base
validates :lst, :presence => true
validates :uuid, :presence => true, :uniqueness => {:scope => :lst}
end
If I try this
f = Favorite.new
f.valid?
I get the following error message:
NoMethodError: undefined method `zero?' for nil:NilClass
from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.0/lib/active_record/associations/alias_tracker.rb:28:in `aliased_name_for'
from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.0/lib/active_record/associations/join_dependency.rb:17:in `initialize'
from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.0/lib/active_record/relation/finder_methods.rb:219:in `new'
from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.0/lib/active_record/relation/finder_methods.rb:219:in `construct_join_dependency_for_association_find'
from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.0/lib/active_record/relation/finder_methods.rb:192:in `exists?'
from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.0/lib/active_record/validations/uniqueness.rb:32:in `validate_each'
from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activemodel-3.2.0/lib/active_model/validator.rb:153:in `block in validate'
from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activemodel-3.2.0/lib/active_model/validator.rb:150:in `each'
from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activemodel-3.2.0/lib/active_model/validator.rb:150:in `validate'
from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.2.0/lib/active_support/callbacks.rb:310:in `_callback_before_15'
from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.2.0/lib/active_support/callbacks.rb:429:in `_run__1275595979440079611__validate__42615372200132002__callbacks'
from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.2.0/lib/active_support/callbacks.rb:405:in `__run_callback'
from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.2.0/lib/active_support/callbacks.rb:385:in `_run_validate_callbacks'
from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.2.0/lib/active_support/callbacks.rb:81:in `run_callbacks'
from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activemodel-3.2.0/lib/active_model/validations.rb:212:in `run_validations!'
from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activemodel-3.2.0/lib/active_model/validations/callbacks.rb:53:in `block in run_validations!'
....
....
ActiveRecord AREL table aliasing is breaking
The error is likely due to ActiveRecord AREL losing track of how to sum an empty array.
The relevant line of code is in the file alias_tracker.rb:
count.sum
If count is an empty array then the line evaluates as:
[].sum
In Ruby that fails:
$ irb
> [].sum
NoMethodError: undefined method `sum' for []:Array
Rails ActiveSupport Enumerable#sum
In Rails that succeeds because ActiveSupport is creating Enumerable#sum
$ irb
> require 'active_support/core_ext/enumerable'
> [].sum
=> 0
Your problem is likely that some unrelated area of your app is also creating Enumerable#sum or Array#sum. The unrelated code is overwriting the Rails method.
The could be happening in your code or in an unrelated gem. The Rails gem loads early, typically first in your Gemfile, and any later gem can interfere with Rails.
How to fix it?
Have you written a method named sum, perhaps within a module named Enumerable or Array? If so, that's a good place to start. You could rename your method, or you could try changing your method to match the Rails method by replacing your #sum code with this code:
module Enumerable
def sum(identity = 0, &block)
if block_given?
map(&block).sum(identity)
else
inject(:+) || identity
end
end
end
If you haven't written a method named sum in your code, then the conflict is likely in a gem you're using. Try commenting-out gems that you're using then reload your app.
You can search for a gem that defines a method named sum like this:
$ cd /usr/lib/ruby/gems
$ find | xargs grep "def sum\b"
Are you using any gems named sixarm? If so, contact me and I'll fix them for you. These are by me, and a few of them do define #sum for use with statistics tools and utilties.
Hope this helps. Can you post here if it solves your issue?

JSON.dump on any ActiveRecord object fails

I've got a project running Rails 3.1.3 and JSON gem 1.6.3, and am unable to pass any ActiveRecord instance to JSON.dump. I always get the following error:
NoMethodError: undefined method `[]=' for #<JSON::Ext::Generator::State:0x000001033f2088>
from /Users/andy/.rvm/gems/ruby-1.9.2-p180#project/gems/activerecord-3.1.3/lib/active_record/serialization.rb:10:in `serializable_hash'
from /Users/andy/.rvm/gems/ruby-1.9.2-p180#project/gems/activemodel-3.1.3/lib/active_model/serializers/json.rb:84:in `as_json'
from /Users/andy/.rvm/gems/ruby-1.9.2-p180#project/gems/activesupport-3.1.3/lib/active_support/json/encoding.rb:47:in `block in encode'
from /Users/andy/.rvm/gems/ruby-1.9.2-p180#project/gems/activesupport-3.1.3/lib/active_support/json/encoding.rb:78:in `check_for_circular_references'
from /Users/andy/.rvm/gems/ruby-1.9.2-p180#project/gems/activesupport-3.1.3/lib/active_support/json/encoding.rb:46:in `encode'
from /Users/andy/.rvm/gems/ruby-1.9.2-p180#project/gems/activesupport-3.1.3/lib/active_support/json/encoding.rb:31:in `encode'
from /Users/andy/.rvm/gems/ruby-1.9.2-p180#project/gems/activesupport-3.1.3/lib/active_support/core_ext/object/to_json.rb:20:in `to_json'
from /Users/andy/.rvm/gems/ruby-1.9.2-p180#project/gems/json-1.6.3/lib/json/common.rb:216:in `generate'
from /Users/andy/.rvm/gems/ruby-1.9.2-p180#project/gems/json-1.6.3/lib/json/common.rb:216:in `generate'
from /Users/andy/.rvm/gems/ruby-1.9.2-p180#project/gems/json-1.6.3/lib/json/common.rb:380:in `dump'
Passing JSON.dump a hash, an instance of a non-ActiveRecord class, etc. work fine, and #to_json works on my ActiveRecord instances. I can't just call #to_json instead, though, as it is actually a library I'm passing my ActiveRecord object to that calls JSON.dump. However I have the same problem skipping that other library altogether and just calling JSON.dump myself.
Any help is much appreciated!
Based on the links below, it sounds like there's an issue with JSON overriding to_json with its own encoding.
https://rails.lighthouseapp.com/projects/8994/tickets/4925-rails-3-to_json-incompatible-with-json-core-library
https://rails.lighthouseapp.com/projects/8994/tickets/4494-ruby-192-heads-json-support-breaks-to_json-for-arrays-of-records
https://github.com/defunkt/resque/issues/149
The workaround that popped up in the threads a few times was to put the following code into your environments.rb file.
class Array
def to_json(*a)
ActiveSupport::JSON.encode(self)
end
end

activerecord-2.3.14 breaks with ruby 1.9.2 ::undefined method `reject' for "4":String

undefined method `reject' for "4":String
is thrown when I try to perform #user.update_attributes(params).
The params list is as follows
"user"=>{"login"=>"admin", "first_name"=>"Admin", "last_name"=>"Admin", "email"=>"nfsurveytest+admin#neurofocus.com", "location_id"=>"1", "last_login_at_text"=>"Never logged in", "password"=>"", "password_confirmation"=>"", "role_ids"=>"4", "active"=>"true", "is_staff"=>"true"},
The error stack is as below
/home/narendra/.rvm/gems/ruby-1.9.2-p290#nf_schedule/gems/activerecord-2.3.14 /lib/active_record/associations.rb:1336:in block in collection_accessor_methods'
/home/narendra/.rvm/gems/ruby-1.9.2-p290#nf_schedule/gems/activerecord-2.3.14/lib/active_record/base.rb:2918:inblock in assign_attributes'
/home/narendra/.rvm/gems/ruby-1.9.2-p290#nf_schedule/gems/activerecord-2.3.14/lib/active_record/base.rb:2914:in each'
/home/narendra/.rvm/gems/ruby-1.9.2-p290#nf_schedule/gems/activerecord-2.3.14/lib/active_record/base.rb:2914:inassign_attributes'
/home/narendra/.rvm/gems/ruby-1.9.2-p290#nf_schedule/gems/activerecord-2.3.14/li b/active_record/base.rb:2787:in attributes='
/home/narendra/.rvm/gems/ruby-1.9.2-p290#nf_schedule/gems/activerecord-2.3.14/lib/active_record/base.rb:2671:inupdate_attributes_inside_transaction'
/home/narendra/.rvm/gems/ruby-1.9.2-p290#nf_schedule/gems/activerecord-2.3.14/lib/active_record/transactions.rb:229:in block in with_transaction_returning_status'
/home/narendra/.rvm/gems/ruby-1.9.2-p290#nf_schedule/gems/activerecord-2.3.14/lib/active_record/connection_adapters/abstract/database_statements.rb:136:intransaction'
/home/narendra/.rvm/gems/ruby-1.9.2-p290#nf_schedule/gems/activerecord-2.3.14/lib/active_record/transactions.rb:182:in transaction'
/home/narendra/.rvm/gems/ruby-1.9.2-p290#nf_schedule/gems/activerecord-2.3.14/lib/active_record/transactions.rb:228:inwith_transaction_returning_status'
/home/narendra/.rvm/gems/ruby-1.9.2-p290#nf_schedule/gems/activerecord-2.3.14/lib/active_record/base.rb:2667:in update_attributes'
/home/narendra/workspace/nf_schedule/app/controllers/users_controller.rb:100:inupdate'
I assume this breaks as String in ruby 1.9.2 does not mixin 'Enumerable'.
Can anyone confirm if this is an issue or I am missing something?
https://github.com/rails/rails/issues/3434
You're supplying a String where ActiveRecord is expecting an Array. You could remap the offending parameter in the controller using something like this:
if (params[:user])
params[:user][:role_ids] = [ params[:user][:role_ids] ]
end
You could also adjust your form so that the field is named role_ids[] instead of just role_ids so that it will be submitted as an array.

Resources