undefined method `get_category' for TestObserver:Class - ruby-on-rails

In TestObserver class, I have self.delivered_email(message) method, the message is the action mailer instance, I'm calling get_category method in self.delivered_email method. But I received error message "undefined method `get_category' for TestObserver:Class". What is the problem and how could I solve it? I'm using observer pattern here in rails.
class TestObserver
def self.delivered_email(message)
begin
category = get_category(message)
# do something here
rescue => ex
# do something here
end
end
private
def get_category(message)
# do something here
end
end
ActionMailer::Base.register_observer(TestObserver)

This is because, you are trying to access a instance method from a class method
your self.delivered_email is a class level method, if it calls other methods those should be class methods too. In this case get_category(message) is a instance method.
To fix the error you could make the get_category(message) as a class method. (if it fits your context)
class TestObserver
def self.delivered_email(message)
begin
category = get_category(message)
# do something here
rescue => ex
# do something here
end
end
def self.get_category(message)
# do something here
end
end

Related

Can't call private class method

Getting the following error when trying to call a private method inside the same class:
undefined local variable or method a_private_method' for AClass (NameError)`
Here the class:
class AClass
def self.public_method
file = a_private_method
end
private
def a_private_method
do something
end
end
You are trying to call an instance method from a class method, this does of course not work.
Try this
class AClass
class << self
def public_method
file = a_private_method
end
private
def a_private_method
# do something
end
end
end
You can also use self as the receiver similar to what you already did but pleases be aware that moving the method to the private part of your class does not work in this case. You could use private_class_method though.
class AClass
def self.public_method
file = a_private_method
end
def self.a_private_method
# do something
end
private_class_method :a_private_method
end
end
See https://jakeyesbeck.com/2016/01/24/ruby-private-class-methods and https://dev.to/adamlombard/ruby-class-methods-vs-instance-methods-4aje.

Need to call self.method in another method with ruby

app/models/product.rb
class Product < ApplicationRecord
def methode1.1
# Do something
end
def method1
# Do something
methode1.1
end
def self.method2
# Do something
method1
end
end
in controller
def Method_4
# Do something
Product.method2
# Do something
end
I call method2 from controller. When I run the program. I got an error:
undefined local variable or method methode1 '' for class
You call a class method Product.method2 and it tries to call an instance method method1. In order to do that, you need to find or initialize an instance of a model, e.g.:
# initialize
def self.method2
# Do something
new.method1
end
or
# find
def self.method2
# Do something
find_by(attr1: val1, attr2: val2).method1
end

how to call define_method in rails after_kind hook

when i call define_method in hook function :
error occurred:
undefined method `define_method' for #<Myentity:0x007f9e4eda5928>
here is an example:
class EntityInstance < ApplicationRecord
after_find :define_relation
def define_relation
define_method "example" do |x|
end
end
end
How to change the context in hook method or how to use this function in hook method?
thx a lot!
define_method should be called in the context of the class.
Meaning, depending on where you want to define the method (either in singleton class of the instance of Myentity or in Myentity class) you should be using either
def define_relation
# define method available only to this particular instance of Myentity
class_eval do
define_method "example" do |x|
end
end
end
or
def define_relation
# define a method available to all instances of Myentity class
self.class_eval do
define_method "example" do |x|
end
end
end

How does one make a Model perform a method on itself?

class MyAwesomeClass
def foobar
puts "trip!"
end
So that I can perform :
MyAwesomeClass.foobar
=> "trip!"
I keep getting :
NoMethodError: undefined method `foobar' for MyAwesomeClass:Class
class MyAwesomeClass
def self.foobar
puts "trip!"
end
end
Using "self" makes the method a class instance method

how to set an instance variable from a class method?

I am trying to do a custom active record macro. But it right now seems impossible set an instance variable from within it's block.. here is what i am trying to do.
module ActiveRecord
class Base
def self.included(base)
base.class.send(:define_method, :my_macro) do |args|
# instance_variable_set for the model instance that has called this
# macro using args
end
end
end
end
i have tried class_eval, instance_eval.. but nothing seems to work or i don't how to use them.
Thanks in advance.
Edit: Let me try to explain better. I have a class method. An instance of the class calls this method. Now, this class method should instruct the instance to set an instance variable for itself.
Edit- this is how i want o use the macro
class MyModel < ActiveRecord::Base
my_macro(*args)
def after_initialize
# use the value set in the macro as #instance variable
end
end
Is this what you are thinking of:
class DynamicAdd
def add_method
self.class_eval do
attr_accessor :some_method
end
end
end
You can then do the following:
k = DynamicAdd.new
k.some_method = "hi"
should result in an undefined method error.
But,
k = DynamicAdd.new
k.add_method
k.some_method = "hi"
should work.
You can use this same format to define other types of methods besides attr_accessors as well:
class DynamicAdd
def add_method
self.class_eval do
def some_method
return "hi"
end
end
end
end
Hm.. Isn't included() a Module method? I don't think you can use that in a class like you have written. If you want to create a class method you can do
class Base
def self.my_method
end
or
class Base
class << self
def my_method
end
end
If all you want to do is to add an instance variable to an existing object, then you can use #instance_variable_set
class Base
class << self
def my_method(instance_of_base, value)
instance_of_base.instance_variable_set "#x", value
end
end
end
a = Base.new
a.class.send(:my_method, *[a,4])

Resources