I finished implementing and testing a controller, then switched back and forth between Git branches and did some merges here and there, etc.
Now I'm unable to use the methods I've defined for the controller, and also very confused, as I'm getting NoMethodError when trying to call them.
Added an edit and solution at the end of the post.
Using Rails version 5.2.3 -
Here I've got my controller defined: app/controllers/paypal_access_token_controller.rb:
class PaypalAccessTokenController < ApplicationController
before_action :authenticate_admin!, only: [:show]
def njurf
puts "#######################"
puts "why can't i call these methods dangit"
puts "#######################"
end
def show
# doesn't really matter
end
def update
# doesn't really matter either
# no syntax errors, I promise
end
end
I'd like the update method to be called when I start the Rails application.
I added PaypalAccessToken.update() to the file config/environments/development.rb - this worked.
Now that I've implemented stuff in other seemingly unrelated parts of the application, I can't call on methods from this controller anymore.
I removed the line from config/environments/development.rb so that I could run the Rails console and added the njurf method to the controller. From the console, I tried calling PaypalAccessTokenController.njurf, and PaypalAccessTokenController.update, but both give me the bespoke NoMethodError.
Here's some proof of concept
Loading development environment (Rails 5.2.3)
irb(main):001:0> PaypalAccessTokenController.update
Traceback (most recent call last):
1: from (irb):1
NoMethodError (undefined method `update' for PaypalAccessTokenController:Class)
irb(main):002:0> PaypalAccessTokenController.update()
Traceback (most recent call last):
1: from (irb):2
NoMethodError (undefined method `update' for PaypalAccessTokenController:Class)
irb(main):003:0> PaypalAccessTokenController.njurf()
Traceback (most recent call last):
1: from (irb):3
NoMethodError (undefined method `njurf' for PaypalAccessTokenController:Class)
So the controller class exists, at least, but I don't know why I'm getting this error - nor do I know how to go about fixing it.
Any help would be appreciated.
edit: This controller only had routes for the show method. I removed this route when I had implemented and tested the update method, because I no longer needed/wanted these methods to be accessible via URLs.
This is what made the methods inaccessible from console.
solution: Either I leave in a route to one of the controller's methods - or, like Ricky Spanish and amit_saxena pointed out below, properly declare the methods as class methods.
Thanks for the replies
You can call it, when you define it with self
def self.njurf
puts "#######################"
puts "why can't i call these methods dangit"
puts "#######################"
end
PaypalAccessTokenController.njurf
#######################
why can't i call these methods dangit
#######################
=> nil
It might look strange, but are you sure you have defined the proper resources on routes?
You cannot access controller methods like that from console as they aren't class methods. You can instead try this:
PaypalAccessTokenController.new.update
but that doesn't mean it's going to work (it probably needs params to work on), but you will not get a NoMethodError. Most probably you messed something in your routes file. You can check the routes using:
bundle exec rake routes
which will tell you exactly which route points to which controller#action and should give you some pointers about what the problem is. Paste the relevant routes here is you are unable to figure it out. Also pay attention to HTTP method (GET/POST/PATCH). You might be using a GET instead of PATCH and getting the error as a result.
Related
I am using a development script file to check out new possible ideas. Recently I tried to monkey patch MyDBObject from within that script file.
Assume an empty dev.rb file and add a monkey patch right in the top like so:
class MyDBObject
def test_function
'function works'
end
end
Starting up the pry console and loading the file yields random results.
First I received:
NoMethodError: undefined method `relations' for MyDBObject:Class
Later the script loaded, but I couldn't access the original class any longer:
undefined method `first' for MyDBObject:Class
I noticed that prepending the line:
MyDBObject
right before the monkey patching, the intended functionality is achieved.
This appears to be some sort of lazy loading of the class objects. Can somebody cast some light on this for me please?
Depending on the order in which source files are loaded, you'll either be redefining the entire class, or having your changes replaced.
I highly recommend giving this a read: http://www.justinweiss.com/articles/3-ways-to-monkey-patch-without-making-a-mess/ (TLDR - put your patch in a module and explicitly include it)
I'm trying to use modules for namespacing reasons. I have this file located in my Rails app at /lib/reports/stripe.rb.
module Reports
module Stripe
def self.foo
puts 'i am foo'
end
end
end
In my console, I'd expect to be able to call foo by Reports::Stripe.foo or Reports::Stripe::foo, but I get the error
NoMethodError: undefined method `foo' for Reports::Stripe:Module
What am I doing wrong? Also feel free to let me know if there's a better way to organize the location and namespacing.
All method calls in ruby use the . syntax. Even "module" methods.
> Reports::Stripe.foo
i am foo
You may be receiving the error NoMethodError: undefined method 'foo' for Reports::Stripe:Module if you have added the method after you have started the rails console. Try restarting the console or reloading the file with load 'reports/stripe'.
The file was actually located in /lib/reports/stripe/stripe.rb. It was a mistake I made much earlier, but forgot to fix. Moving the file to /lib/reports/stripe.rb resolved the issue.
I'm experimenting with n+1 queries in the rails console, but running
> Zombie.include(:brain).all.each do |z| z.brain end
Results in this error:
NoMethodError: private method `include' called for #<Class:0x000000045bf2a8>
Is there anway I can access the include method? A sort of sudo method that gives the console access to all of my application's methods?
I'm fairly sure you want includes there :)
includes comes from ActiveRecord::Base
include comes from Module
So when I submit all the info to create a new user: i get this error:
NoMethodError in UsersController#create
undefined method `sign_in' for #
I googled for it first and found answers where I was supposed to create a sessions_helper.rb file and include it in application.rb , did it all and when I refreshed after each step, it seemed to work. But now when I reloaded the page from the start again, I got the same error again.
Veske showed me his code: https://gist.github.com/Veske/7536022
You have to define your method in the SessionHelper, it is not going to automatically be made for you :)
You need to create a sign_in method in at least the SessionsHelper class.
If you'd like to use the devise gem for users creation/authentication, you'll have that method available in your code directly.
I have a problem on my ruby on rails application. It uses too much memory whenever it encounters an undefined method. It freezes the server until I kill the process. Error log points to the undefined method that goes to something like this:
ActionView::Template::Error (undefined method `testos' for #<#:0x007fb3d88de8c8>):
Is there any way or configuration to fix this? I am using ruby 1.9.3 on rails 3.2.2.
Here is the stack trace
Completed 500 Internal Server Error in 53960ms
ActionView::Template::Error (undefined method testos' for #<#<Class:0x007fb3d43d0420>:0x007fb3d479c8d8>):
77: #rules["data"].each do |rule|
78: json_rule =ActiveSupport::JSON.decode(rule["json_rule"])
79: %>
80: <%=testos(1)%>
81: <div class="dvGridRow" style="width:100%;padding-bottom:10px;">
82: <div class="dvGridData" style="vertical-align:top;width:190px;margin-left:5px;">
83: <%= json_rule["rule_name"]%>
app/views/rules/index.html.erb:80:inblock in _app_views_rules_index_html_erb_4146358986539966513_70205169705180'
app/views/rules/index.html.erb:77:in each'
app/views/rules/index.html.erb:77:in
_app_views_rules_index_html_erb_4146358986539966513_70205169705180'
Rendered /Users/jay/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.2/lib/action_dispatch/middleware/templates/rescues/_trace.erb (6.4ms)
cache: [GET /manage/rules] miss
Rendered /Users/jay/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.2/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (1.8ms)
Rendered /Users/jay/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.2/lib/action_dispatch/middleware/templates/rescues/template_error.erb within rescues/layout (18.5ms)
note:
I intentionally called an unidentified method, because I am trying to figure out where does my code freezes the machine, and that error causes it.
Thanks
A Problem (and a Solution)
Let’s say your working with a Ruby object. And let’s also say that you aren’t entirely familiar with this object. And let’s also say that you call a method that doesn’t exist on the object.
o = Object.new
o.some_method
NoMethodError: undefined method `some_method' for #
This is less than desirable, so Ruby has an awesome way of allowing us to rescue ourselves from this. Check this out:
class OurClass
def method_missing (method_name)
puts "there's no method called '#{method_name}'"
end
end
o = OurClass.new
o.some_method
=> there's no method called 'some_method'
We can create a method called method_missing in our class. If the object we’re calling the method on doesn’t have the method (and doesn’t inherit the method from another class or module), Ruby will give us one more chance to do something useful: if the class has a method_missing method, we’ll hand the information about the method cal to method_missing and let it sort the mess out.
Well, that’s great; we’re no longer getting an error message.
reference from this link
http://net.tutsplus.com/tutorials/ruby/ruby-for-newbies-missing-methods/