Supposing I have a model A like:
class A
def self.base_attributes
{:state_a => nil}
end
def self.aa(params)
instance = load
instance.state_a = {:xx => params[:x]...}
instance
end
def cc(x)
self.state_a[..] = x
self.save!
end
end
and I have a controller B like:
controller B
def mtd
#aaa = A.aa(params)
#operations to get y
#aaa.cc(y)
end
end
Is there a way in which I can make the model method cc(x) a static method and call it from the instance variable of the controller (#aaa)?
Is there a way in which I can make the model method cc(x) a static
method and call it from the instance variable of the controller
(#aaa)?
A static class method has to be called with the class object as the receiver, and an instance method has to be called with the instance method as the receiver.
Why do you care what type of method it is if you are going to call it with the instance?
Response to comment:
Then the instance that load() returns is not an instance of class A. It's very simple to test that what you want to do works: in one of your actions in your controller write:
#my_a = A.new
#my_a.do_stuff
Then in your model write:
class A
def do_stuff
logger.debug "do_stuff was called"
end
...
...
end
Then use the proper url, or click the proper link to make that action execute. Then look at the bottom of the file:
log/development.log
...and you will see a line that reads:
"do_stuff was called"
You can also record the type of the object that load() returns by writing:
def self.aa(params)
instance = load
logger.debug instance.class #<===ADD THIS LINE
instance.state_a = {:xx => params[:x]...}
instance
end
It's not clear what load does, but in any event, if #aaa is an instance of A and cc is a class method of A, then you can invoke cc with the expression #aaa.class.cc.
Related
What is the correct structure to be able to call a class from another class?
I can call MyObject.new by using MyModule::MyClass::MyObject.new()
However, I would prefer to call it using:
MyModule::MyClass.myobject.new()
How do I structure my code to by able to do this?
module MyModule
class MyClass
class MyObject
def initialize(value)
#value = value
end
def method1
"This is a #{value}"
end
end
end
end
You need to define a method myobject on MyClass which returns MyObject...
module MyModule
class MyClass
class MyObject
end
def self.myobject; return MyObject; end
end
end
If I understand you correctly, you have a variable of some class and want to create a new object of the same class. Assuming that your classes all have an empty constructor, you could do a
myobject.class.new()
If you want to also have the new object the same internal state as the other one, write a method
class MyMethod
def clone
...
end
end
which performs this task.
The Answers here are right, but don't do this it's not standard and will be confusing for anyone who reads your code.
MyModule::MyClass.my_object_instance
class MyClass
def self.my_object_instance
MyObject.new
end
end
this could be better to create a factory method that returns a new instance of the class if want a shorter way to create an instance of the class.
I am very new to RoR and I have played around the source code. But I have a problem that I already built a 'def A' for creating first CSV file, and 'def B' for creating second CSV file. Each 'def' has its own button, but I have the third button to create all CSVs (to produce output from first and second CSV files.)
What is the possible way to do it?
def first_csv
...
end
def second_csv
..
end
def all_csv
<< how to call get first and second csv >>
end
Thanks in advance,
It should be as simple as you imagine:
def all_csv
first_csv
second_csv
end
Muntasim's answer is correct, but I have to add some additional information.
Ruby provides two types of methods..class methods and instance methods.
class MyClass < AvtiveRecord::Base
# class method
def self.foo
# do something
# within this scope the keyword "self" belongs to the class
end
# another class method which calls internally the first one
def self.bar
something = foo # self.foo could also be written
# do something with something
# within this scope the keyword "self" belongs to the class
end
# instance method
def foo
# do something
# if you use the keyword "self" within an instance method, it belongs to the instance
end
# another instance method which calls class and the first instance method
def bar
mystuff = Myclass.bar # if you want to call the class method you cannot use "self", you must directly call the class
mystuff2 = foo # self.foo is the same, because of the instance scope
return [mystuff, mystuff2]
end
end
You can call the last instance method like following
instance = MyClass.first
instance.bar
hi i am new ruby on rails i need to know some basic information about
how to call a function from controller to model
for ex:-
controller name : checkings
def create
#data = Checking.check()
end
model name is Checking
def check
#a="xxxxx"
end
how can i call from controller function to model function
check is instance method,you have to make class method to call by class name,def self.check end
Seems you are referring to static function call. In ruby the static functions are defined with self.
def self.check
a="xxxxx"
end
However, in rails, you should not populate instance variable in Model. In that case you can return the value from check function and assign it in controller function like
def self.check
return "xxxxx"
end
#In controller
#data = Checking.check() # "xxxxx" will be stored in #data
However, defining any function without self means its a instance function. So you need to call that function through any object of that class.
We can call the model methods from controller using two formates,
1 . Creating singleton methods.
Singleton methods are created using self keyword. example
class Check < ActiveRecord::Base
def self.check
end
end
we can call this singleton method using following format,
#checks = Check.check
2 . Creating instance methods.
Instance methods are created using without self keyword
class Check < ActiveRecord::Base
def check
end
end
we can call this singleton method using following format,
#check =Check.new
#checks = #check.check
Hey guys.
How do I know the methods that a child class overrided in my super class?
I have this:
class Test
def self.inherited(child)
# child.overrided_methods???
end
def self.foo
end
def self.bar
end
end
def Child < Test
def self.bar
puts "bar"
end
end
The method self.inherited is called when a subclass of Test is loaded. So I get the reference to this subclass in child, but I don't know how to get the methods that were overrided by this subclass.
Any ideas?
--
Arsen suggested the use of self.method_added(name) instead of self.inherited(child), but this method catches only instance methods and I want to catch class methods. Does anyone know another methods that does the same thing but with class methods?
In the last case I'll consider using a singleton and convert all this class methods to instance methods then the problem is solved.
For instance methods there is an Object::method_added(name) method you can override, similar to 'inherited' you have used:
class test
def self.method_added(name)
puts "method_added(#{name.inspect})"
super
end
end
irb(main):002:0> class Child < Test; def foo; end; end
method_added(:foo)
=> nil
You can then compare a received name to a list of your methods:
Test.instance_methods.include?(name.to_s)
With class methods this approach does not work (even if you do things like class << self magic), but a helpful fellow knew the answer: http://www.ruby-forum.com/topic/120416 :
class Test
def self.singleton_method_added(name)
puts "Class method added #{name.inspect}"
end
end
This is only the first part of the problem, because you need to know which class defined the method (it will be self) and whether the method is a new one, or overridden one. Experiment with this code:
class Test
def self.singleton_method_added(name)
if self == Test
puts "My own class method added: #{self.name}.#{name.inspect}"
elsif Test.methods(false).include?(name.to_s)
puts "Class method overriden: #{self.name}.#{name.inspect}"
elsif Test.methods(true).include?(name.to_s)
puts "My parent's class method overriden: #{self.name}.#{name.inspect}"
else
puts "New class method added: #{self.name}.#{name.inspect}"
end
end
end
Maybe a first step to the solution:
By calling child.instance_method(:bar) (if child refers to the class) or child.method(:bar) (if it refers to an instance of Child) you can get an UnboundMethod or Method object representing your method:
a = Test.instance_method(:foo)
b = Child.instance_method(:foo)
Unfortunately, a == b evaluates to false, although both refer to the same method.
def overridden_methods
klass = self.class
klass.instance_methods.select {|m| klass.instance_method(m).owner == klass}
end
Change according to your needs.
I have a model called Action. It looks like this:
class Action < ActiveRecord::Base
def register_action(email,type)
#action = new()
#action.guid = "123456789"
#action.email = email
#action.action = type
action.guid if #action.save
end
end
If I try and access this class from my user_controller, I get an error.
The code I'm trying to use is :
if (#User.save)
guid = Action.inspect()
guid = Action.register_action(#User.email,"REGISTER")
MemberMailer.deliver_confirmation(#User,guid)
end
Action.inspect() works fine, so I'm guessing that the Action class can be seen, but the line which calls register_action returns the following error:
NoMethodError in UserController#createnew
undefined method `register_action' for #<Class:0x9463a10>
c:/Ruby187/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/base.rb:1994:in `method_missing'
E:/Rails_apps/myapp/app/controllers/user_controller.rb:32:in `createnew'
What am I doing wrong?
I'm new to Rails so apologies for being stupid.
Problem is on this line:
guid = Action.register_action(#User.email,"REGISTER")
register_action is an instance method, not a class method, so you call it on an instance of the Action class, not the Action class itself.
If you want to define register_action as a class method, you should do so like this:
def self.register_action(email, type)
# ... Body ...
end
Change
def register_action(email,type)
to either
def self.register_action(email,type)
or
def Action.register_action(email,type)
In your register_action method you need to do #action = Action.new instead of #action = new(). Alternatively, you can construct it like this:
#action = Action.new(:guid => "123456789", :email => email, :action => type)
Also, you have defined register_action as an instance method on your Action class, but you're calling it as a class method by using Action.register_action. Change it to:
def self.register_action(email, type)
...
end