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
Related
This is a hard one to search for, but I've got a line of Ruby in a class method where a variable is first declared by assigning it a bare new keyword and I'm not exactly sure what's going on here:
def self.html_render_controller(post)
controller = new
controller.action = 'show'
controller.post = post
controller.render_to_string
end
Coming from other languages, it looks to me like controller is implicitly being initialized as an object of some kind. And render_to_string is a Rails built-in, so my best guess is controller is initialized as some kind of Rails object?
I guess my question is really what is the value of controller after that first assignment? Or what kind of execution rules or even just documentation in Ruby would point me in the right direction for understanding this kind of shorthand?
It is not so weird as ruby code. It Is quite straight forward.
new is not a keyword is a method called on the implicit self.
You do not need parenthesis to call a method in Ruby.
If you call a method without an explicit receiver in Ruby, the receiver is going to be self, inside the body of the method self.html_render_controller, self references the class where the method is defined.
So executing new inside the method self.html_render_controller just return a new object of the class where the method is defined.
You can have more details on new from the documentation on Class, that is the class of any class in Ruby, being a class just an object of the class Class.
I'm not exactly sure what's going on here
It's the new method of your class, i.e. it returns a new instance of the class your html_render_controller method is defined in.
Since you come from other languages, it might be easier to think of controller = new() (which in fact works just fine in Ruby, but it's more idiomatic to omit empty parentheses unless needed)
what kind of execution rules or even just documentation in Ruby would point me in the right direction for understanding this kind of shorthand?
This is Ruby's default method calling mechanism when omitting a receiver: "self is the default receiver. If you don't specify any receiver self will be used."
In instance methods, self refers to the current instance. In class methods, self refers to the class the method is defined in.
These three code snippets are all equivalent: *
class MyController
def self.foo
controller = new
end
end
class MyController
def self.foo
controller = self.new
end
end
class MyController
def self.foo
controller = MyController.new
end
end
You could also replace the self after def with the class name:
class MyController
def MyController.foo
controller = MyController.new
end
end
And using the latter, most explicit form, the method could even be defined outside the class body:
class MyController
end
def MyController.foo
controller = MyController.new
end
* Note that the above examples are not identical. For example, with sub-classes, self.new would dynamically create an instance of the respective (sub-)class whereas MyController.new would always create an instance of MyController. And you usually want to define your methods within the class body to ensure proper constant lookup.
new is instantiating an object of the class where this html_render_controller method is.
You can change it to self.new instead of new, then it's clearer where this method is coming from. Since html_render_controller is a class method, self will be the class where the method is.
class Foobar
def self.foo
foobar = new
# `foobar` is a new instance of Foobar
end
end
I have a user model in my application. Now I want to replace some user model coding into 2 categories likely employ.rb and customer.rb under a module users, to avoid more number of codes in a single model. I want to access a method send_mail in customer.rb after a user created.
user.rb
after_create:send_msg_on_order
def send_msg_on_order
Users::Customer.send_mail
end
users/customer.rb
def send_mail
Mailer.send_mail_to_customer.deliver
end
And I am getting undefined method `send_mail' for Users::Customer:Module error.
You have defined send_mail method as instance method but calling it as a class method. Either make it a class method or create an instance of Customer model and call it.
Making the method a class method:
def self.send_mail
Mailer.send_mail_to_customer.deliver
end
If you wish to keep it an instance method, then call it like this:
after_create:send_msg_on_order
def send_msg_on_order
Users::Customer.new.send_mail
end
HTH
You can also call like this
def send_msg_on_order
Customer.send_mail
end
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.
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
I'm have some difficulties here, I am unable to successfully call a method which belongs to a ProjectPage model in the ProjectPage controller.
I have in my ProjectPage controller:
def index
#searches = Project.published.financed
#project_pages = form_search(params)
end
And in my ProjectPage model:
def form_search(searches)
searches = searches.where('amount > ?', params[:price_min]) if check_params(params[:price_min])
#project_pages = ProjectPage.where(:project_id => searches.pluck(:'projects.id'))
end
However, I am unable to successfully call the form_search method.
To complete davidb's answer, two things you're doing wrong are:
1) you're calling a model's function from a controller, when the model function is only defined in the model itself. So you do need to call
Project.form_search
and define the function with
def self.form_search
2) you're calling params from the model. In the MVC architecture, the model doesn't know anything about the request, so params is not defined there. Instead, you'll need to pass the variable to your function like you're already doing...
Three thing:
1.) When you want to create a class wide method thats not limited to an object of the class you need to define it like
def self.method_name
..
end
and not
def method_name
...
end
2.) This can be done using a scope with lambda these are really nice features. Like This in the model add:
scope :form_search, lambda{|q| where("amount > ?", q) }
Will enable you to call
Project.form_search(params[:price_min])
The secound step would be to add a scope to the ProjectPage model so everything is at the place it belongs to!
3.) When you call a Class method in the Controller you need to specifiy the Model like this:
Class.class_method
Declare like this in model
def self.form_search(searches)
searches = searches.where('amount > ?', params[:price_min]) if check_params(params[:price_min])
#project_pages = ProjectPage.where(:project_id => searches.pluck(:'projects.id'))
end
and call from controller
#project_pages = ProjectPage.form_search(params)