Access private methods in the rails console - ruby-on-rails

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

Related

NoMethodError in controller that has methods defined

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.

Extending ActiveRecord in rails 4.2

I've followed this guide:
http://guides.rubyonrails.org/plugins.html#add-an-acts-as-method-to-active-record
In fact, I've actually copied the code and put into my app and it doesn't work.
I keep getting undefined method errors.
When I use console, I can check if the module is initialized and it is, but the model that uses the "acts_as" method throws undefined method errors.
Also in console I can call ActiveRecord::Base.send :include, ... explicitly and then it includes the module -- then everything works. But try as I may, I can't get rails to call .send on ActiveRecord::Base at load time.
Any ideas?

Namespace module class methods undefined

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.

How do I call ActiveRecord::Attributes::ClassMethods#columns?

I have an ActiveRecord class MyClass with some fields in the database and which includes this concern:
module Wrapper
extend ActiveSupport::Concern
included do
puts self #=> MyClass
puts self.columns #=> Array of ActiveRecord::ConnectionAdapters::PostgreSQLColumn
end
end
The first time I access this class (e.g. MyClass.first) I get the expected output (as above).
If I try calling MyClass.first a second time then no output appears, and if I run MyClass.columns without including the concern I get:
output error: #<NoMethodError: undefined method 'name' for #<Object:0x007fd1f20d0ef0>>
Can you help me understand what's going on here?
The method in question is ActiveRecord::Attributes::ClassMethods#columns.
I understand that the code in the included block is scoped to the context of the class which makes sense (making this issue more mysterious).
It would also be great if you could:
Let me know how I could have debugged it further (e.g. how do I identify which object it is that doesn't have the 'name' method)?
Point me to any resources / tutorials that explain this concept
I'm running Rails 4.2.0 and Ruby 2.2.0

How to successfully inherit ActiveRecord::Base?

How to successfully inherit ActiveRecord::Base?
Environment: Ruby 2.0.0, Rails 4.0.3, Windows 8.1, PostreSQL 9.3.3, Devise 3.2.4
I have an operational app and would like to add a comprehensive logging class to it. This will be a complex class that not only logs messages but also creates an SQL database that logs transactions by object. I need this class available throughout all of the classes in the application.
To do this, I wanted to inherit ActiveRecord::Base into the class and then have all other classes inherit it, though I don't plan to use STI. That seemed to be a lot simpler in concept than in practice, even though I thought such inheritance was a common best practice. Am I missing something?
One of the initial tables was this:
class Device < ActiveRecord::Base
...
end
I set it up like this:
class XLog < ActiveRecord::Base
self.abstract_class = true
def initialize
end
end
class Device < XLog
...
end
Prior to this change, the app was working fine. After this change, when I login I receive:
ArgumentError at /devices/sign_in
wrong number of arguments (1 for 0)
The error occurs in:
bin/rails, line 4
bin/rails is:
#!/usr/bin/env ruby.exe
APP_PATH = File.expand_path('../../config/application', __FILE__)
require_relative '../config/boot'
require 'rails/commands'
Device is the Devise "User" class in this application and the error occurs when I try to login. If I change Device to inherit ActiveRecord::Base, it lets me login and run.
But, then I get another error whenever I call "new" on the other classes:
undefined method `[]' for nil:NilClass
I am definitely missing something when it comes to this inheritance. Advice appreciated.
The initialize method was throwing the error. It was triggering every time a subclass was initialized and was configured to accept 0 parameters. When I removed it, the whole thing started working. If I need it, I'll have to configure it to accept a variable number of parameters and pass them as expected, I guess.

Resources