Rails: "NoMethodError: undefined method `constructKDTree' for #<Class:0x00000104b1f760>" - ruby-on-rails

Hi there I have 3 files in rails as follows:
1)Located at "app/controller/listings_controller.rb"
class ListingsController < ApplicationController
def index
#Construct kd Tree in memory
#tree = Listing.constructKDTree;
#tree.inspect
end
2) Located at app/models/listing.rb
require 'kd_tree.rb'
class Listing < ActiveRecord::Base
def constructKDTree
#contents = self.all
#kdTree = KDTree.new(#contents)
end
3) Located at app/models/kd_tree.rb
class KDTree
def initialize (db_listings)
'Initializing Tree'
end
end
Now I'm trying to test the method implementation for constructKDTree so I went to my rails console and tried the following commands:
1.9.2-p290 :001 > #lc = ListingsController.new
=> #<ListingsController:0x00000104f3e288 #_routes=nil, #_action_has_layout=true, #_headers={"Content-Type"=>"text/html"}, #_status=200, #_request=nil, #_response=nil>
1.9.2-p290 :002 > #lc.index
But I get this error:
NoMethodError: undefined method `constructKDTree' for #<Class:0x00000104b1f760>
from /Users/AM/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.1/lib/active_record/dynamic_matchers.rb:50:in `method_missing'
from /Users/AM/Documents/RailsWS/cmdLineWS/Businesses/app/controllers/listings_controller.rb:20:in `index'
from (irb):2
from /Users/AM/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.2.1/lib/rails/commands/console.rb:47:in `start'
from /Users/AM/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.2.1/lib/rails/commands/console.rb:8:in `start'
from /Users/AM/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.2.1/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
What am I doing wrong?

You defined constructKDTree as an instance method on Listing. Thus the method is only available on instances of the class but nit the class itself.
Depending on what you actually want to achieve, you can make the method a class method like it's done in the following code, or you could create a new instance of the Listing class and call the method on the instance.
class Listing < ActiveRecord::Base
def self.constructKDTree
#contents = self.all
#kdTree = KDTree.new(#contents)
end
end
However looking at the code you have there, you probably want to do the latter and create a new instance of the class:
listing = Listing.new
#tree = listing.constructKDTree

This is a call to a class method:
#tree = Listing.constructKDTree
This is a definition of an instance method:
def constructKDTree
#contents = self.all
#kdTree = KDTree.new(#contents)
end
You want constructKDTree to be a class method so you need to say this:
def self.constructKDTree
#...

Related

Rails: Uninitialized constant - can not access to another class from controller

search_handlers_controller.rb
class SearchHandlersController < ApplicationController
def match
#string = 'string'
#result = case params['search_style']
when 'match'
MatchService.call(#string)
...
MatchService.rb in /services:
# frozen_string_literal: true
class MatchService < ApplicationService
...
def call(string)
'Match'
end
end
Error when calling MatchService from SearchHandlersController#match:
NameError (uninitialized constant SearchHandlersController::MatchService):
app/controllers/search_handlers_controller.rb:18:in `match'
First of all, if you named the file MatchService.rb, you should change name of this file into match_service.rb.
If this isn't work in your case, you can always call the service from the root by add :: before the service name like that: ::MatchService.call(#string).
I hope it helps you!

Uninitialized constant error in Ruby class

I have these two classes in RubyMine:
book.rb:
class Book
def initialize(name,author)
end
end
test.rb:
require 'book'
class teste
harry_potter = Book.new("Harry Potter", "JK")
end
When I run test.rb, I get this error:
C:/Users/DESKTOP/RubymineProjects/learning/test.rb:3:in `<class:Test>': uninitialized constant Test::Book (NameError)
from C:/Users/DESKTOP/RubymineProjects/learning/test.rb:1:in `<top (required)>'
from -e:1:in `load'
from -e:1:in `<main>'
You're getting the error because your require 'book' line is requiring some other book.rb from somewhere else, which doesn't define a Book class.
Ruby does not automatically include the current directory in the list of directories it will search for a require so you should explicitly prepend a ./ if you want to require a file in the current directory, ie.
require './book'
You have defined the initialize method but forgot to assign the values into instance variables and a typo in your code triggered the error, fixed it as:
book.rb
class Book
def initialize(name,author)
#name = name
#author = author
end
end
test.rb
require './book'
class Test
harry_potter = Book.new("Harry Potter", "JK")
end
So, which book or resource are you following? I think you should at least complete a book to get proper knowledge of Ruby and Object Oriented Programming. I would suggest you 'The Book of Ruby' to start with.
In a Rails app this error can also be caused by renaming the class without renaming the file to match, which was my issue when I found this error:
book.rb
class Book
def initialize(name, author)
end
end
book_test.rb
class BookTest
harry_potter = Book.new("Harry Potter", "JK")
end

NameError: undefined method `xyz' for class `State' in rails 4

In model:
class State < ActiveRecord::Base
belongs_to :country
alias_method :abc, :xyz
def self.xyz
end
end
In log:
1.9.3-p551 :005 > State.abc
NameError: undefined method 'xyz' for class 'State'
I am new to alias_method in rails. Please help me out.
This is nothing to do with Rails, alias_method is part of ruby itself, which you really should learn before trying to use Rails.
Your problem here is that you've defined xyz as a class/singleton method, but alias_method called as you've done works on instance methods.
You can try the following :
class State
def self.xyz
ap 'inside'
end
self.singleton_class.send(:alias_method, :abc, :xyz)
end
Following should work :
>> State.xyz
>> State.abc

Using Rails view helpers with Haml::Engine

I have a Rails app in which I am rendering a block of Haml stuff stored in a model attribute. It would be nice to use Rails view helpers in that block of Haml. Currently I am using the Haml::Engine#render in a view helper to render the content of this model attribute. It works well enough but I can't use things like =link_to. To illustrate the problem:
irb(main):003:0> haml_text=<<"EOH"
irb(main):004:0" %p
irb(main):005:0" =image_tag 'someimage'
irb(main):006:0" EOH
=> "%p\n =image_tag 'someimage'\n"
irb(main):007:0> engine = Haml::Engine.new(haml_text)
=> #<Haml::Engine:0x7fa9ff7f1150 ... >
irb(main):008:0> engine.render
NoMethodError: undefined method `image_tag' for #<Object:0x7fa9ff7e9a40>
from (haml):2:in `render'
from /usr/lib/ruby/gems/1.8/gems/haml-3.0.25/lib/haml/engine.rb:178:in `render'
from /usr/lib/ruby/gems/1.8/gems/haml-3.0.25/lib/haml/engine.rb:178:in `instance_eval'
from /usr/lib/ruby/gems/1.8/gems/haml-3.0.25/lib/haml/engine.rb:178:in `render'
from (irb):8
Any thoughts on how to do that?
Better ideas?
The render method allows you to specify a context. Something like
base = Class.new do
include ActionView::Helpers::AssetTagHelper
include ApplicationHelper
end.new
Haml::Engine.new(src).render(base)
could work.
Marcel was going in the right direction. But you need to get a valid scope for the render engine from somewhere. What I did was call the helper with a valid scope like this:
In my_view/edit.html.haml
=my_revertable_field(self, 'hello world')
In application_helper.rb
def my_revertable_field(haml_scope, title, field)
template =<<EOS
.field
#{label}
= text_field_tag #{field.name}, #{field.amount}, :size=>5, :class=>"text"
= image_tag("refreshArrow.gif",:class=>"revert-icon", :style=>"display:none;",:title=>"Revert to default, #{field.default}")
EOS
end
Then you have a valid haml scope and so image_tab, form_tag_helpers all work
class RailsRenderingContext
def self.create(controller)
view_context = ApplicationController.helpers
class << view_context; include Rails.application.routes.url_helpers; end
view_context.request = controller.request
view_context.view_paths = controller.view_paths
view_context.controller = controller
view_context
end
end
class MyController < ApplicationController
def show
# ...
engine = Haml::Engine.new haml
ctx = RailsRenderingContext.create(self)
engine.render ctx
end
end
It works for me. Based on this issue.

Why do I get missing method in the following situation?

I have two problems but I'll post them as 2 different questions. Let's start with the first one.
class Order < AbstractOrder
def update_status
self.all_created.each do |order|
order.status = :in_progress
order.save
end
end
end
In my specs when I try to call
Order.update_status
I get an error saying :
Failure/Error: Order.update_status
NoMethodError:
undefined method `update_status' for #<Class:0x00000103f256a8>
# ./spec/models/order_spec.rb:17:in `block (3 levels) in <top (required)>'
Finished in 0.10439 seconds
3 examples, 1 failure
Why? I thought this was a class method not an instance method. If I create an order and do order.update_status it works. What is wrong and how do I fix it?
To bind the method to the class object you need to define it as self.update_status, and the self before all_created shouldn't be necessary:
class Order < AbstractOrder
def self.update_status
all_created.each do |order|
order.status = :in_progress
order.save
end
end
end

Resources