Rails 3: Call Functions Inside Controllers

Rails 3: Call functions inside controllers

if you want it to be local to a controller then all you need to do is to add it to the controller you wish to use.

private
def myfunction
function code.....
end

to all controllers you can put it inside the application controller, because all controlers are sub classed.

ApplicationController

protected

def myfunction

function code.....

end

If you want access in your views then you can create a helper

ApplicationHelper

def myfunction

function code...

end

How to call a Model Method from a Controller in Rails 3?

It seems @var is empty at that point

you should use something like (choose one):

@var = Var.find params[:id]
#or
@var = Var.new
#or
@var = Var.create

then you could call your

@var.model_method

Calling helper method from Rails 3 controller

 view_context.some_helper_method

How to call a method of a controller in a method of another controller

Why not define the shared method in ApplicationController instead and call it in both controllers as they each inherit it's methods. Like so:

ApplicationController:

class ApplicationController < ActionController::Base

protected

def update(var)
var1 = var
end
end

Other Controllers:

class SomeController < ApplicationController    
def some_method()
@var = 'something'
update(@var)
end
end

class SomeOtherController < ApplicationController
def some_method()
@var = 'something'
update(@var)
end
end

Call inner controller actions and send params between them rails

You should not call an action of your controller from another action.

Why? Because every action of a controller is defined to respond to a request, which has several attributes (such as IP, params, session, HTTP headers, etc.). Imagine how "weird" it would be to call an action from another in the Controller.

If you want to do "extra logic" which would not be related to the update action (for example, create), you should call a protected (accessible only via the Controller & its children) method of this controller.

In your case, you could do something like this:

class ReportsController < ApplicationController
def update
@report = Report.where(id: params[:report_id]).first
if @report.nil?
create_report(params)
else
# etc.
end
end

protected

def create_report(params)
Report.create(params)
end
end

Calling a method from another controller

You could technically create an instance of the other controller and call methods on that, but it is tedious, error prone and highly not recommended.

If that function is common to both controllers, you should probably have it in ApplicationController or another superclass controller of your creation.

class ApplicationController < ActionController::Base
def common_to_all_controllers
# some code
end
end

class SuperController < ApplicationController
def common_to_some_controllers
# some other code
end
end

class MyController < SuperController
# has access to common_to_all_controllers and common_to_some_controllers
end

class MyOtherController < ApplicationController
# has access to common_to_all_controllers only
end

Yet another way to do it as jimworm suggested, is to use a module for the common functionality.

# lib/common_stuff.rb
module CommonStuff
def common_thing
# code
end
end

# app/controllers/my_controller.rb
require 'common_stuff'
class MyController < ApplicationController
include CommonStuff
# has access to common_thing
end

Calling a method of another controller

Easy. Make the method .self

class MotherController < ApplicationController
def self.get_details(data)
end
end

And then:

class ChildrenController < ApplicationController
def set_details
MotherController.get_details(data)
end
end

Rails 3, make submit call specific function in controller

You did not include the view logic so I am going to take a stab in the dark and guess you are writing the HTML for the form rather than using the RoR helpers.

In rails there are a set of helpers that help you generate forms and form items.

Please check the docs for form_for

Using form_for will follow the basic restful routing unless you modify the url parameter. So if you are on /new you will be routed to /create, if you are on /edit, you will be routed to /update. More precisely, if the object is new, you will submit to create, if the model exists you will submit to update.

If your form doesn't use a model, you can use the form_tag helper that takes a url parameter and you can pass a string specifying what path to submit to.

If you just need to know how to do this in plain HTML, read this. Essentially, you need to include an action attribute on form that specifies the path to the action you want to post to.

How to call a controller's method from a view?

The method option in a link_to method call is actually the HTTP method, not the name of the action. It's useful for when passing the HTTP Delete option, since the RESTful routing uses the DELETE method to hit the destroy action.

What you need to do here, is setup a route for your action. Assuming it's called join_event, add the following to your routes.rb:

match '/join_event' => 'controllername#join_event', :as => 'join_event'

Be sure to change controllername to the name of the controller you are using. Then update your view as follows:

<%= link_to 'Join', join_event_path %>

The _path method is generated based on the as value in the routes file.

To organize your code, you might want to encapsulate the inserts into a static model method. So if you have a model called MyModel with a name column, you could do

class MyModel
# ...
def self.insert_examples
MyModel.create(:name => "test")
MyModel.create(:name => "test2")
MyModel.create(:name => "test3")
end
end

Then just execute it in your action via:

MyModel.insert_examples

Calling a method from a controller in Rails?

Firstly, let me say that your approach is not that wrong imho. Introducing an extra method which is just an alias for Page.all is not really needed, or not really an improvement.

But there are definitely better approaches.

I would fix this as follows: in ApplicationController I would add the method

def get_all_pages
@pages ||= get_all_pages
end

This will make sure that any controller knows that method.

Then, if you are sure, you need it on every page, you can just a before_filter in your ApplicationController, but generally, I prefer to write it in the controller itself.

E.g.

class IdeasController < ApplicationController

before_action :get_all_pages

... the rest of your controller ...

end

Also, I would extract your list of pages into a partial, store in under app/views/shared/_pages_list.html.erb or app/views/pages/_pages_list.html.erb and then in your application.html.erb just call to render the partial instead.

The method we called sets the instance variable @pages, it will be available in the view, so your partial would like:

<ul>
<% @pages.each do |page| %>
<li><%= link_to page.name, page_path(page) %></li>
<% end %>
</ul>

Lastly, for completeness, let me answer how you can make a controller-method available in the view. In a controller write

def get_pages
# ..do something
end
helper_method :get_pages

This will make the method get_pages available in the view, but only for a controller that was responsible for loading/rendering that view. So if you want it for all views, define this in ApplicationController. E.g. this is what we generally do when defining current_user method.

Further improvements/alternatives

  • if you start to get some more code, extract the code related to the page-list-fetching-and-rendering into a separate module, and include that into your ApplicationController. This makes your ApplicationController more readable.

    • Note: this is exactly what concerns were introduced for, so you can use that, if you are on rails 4
  • a Page is its own resource, so you could always create a separate PagesController and make sure it is responsible for rendering the list, and use ajax to fetch on the pages where it is needed. This is a really nice solution, but also a bit more work (overkill?). But very nicely structured.

  • This problem, where you have different areas on a page, which each should have their own Controller-Model-View, is exactly what the cells gem gem solves in a very clean way. There is a very good example of rendering a shopping-cart on the page I linked, so you could always check that out.


Related Topics



Leave a reply



Submit