9

I am very new to ruby. I have one doubt, how to call a controller method from a view.

my controller

def course_user_count
 @courses=Course.all
 @courses.each do |course|
 @count=course.students.count
end

I have to call this @count variable from the method in my view course.view.html.erb

Jamie Taylor
  • 4,709
  • 5
  • 44
  • 66
saran
  • 404
  • 2
  • 4
  • 9
  • 1
    possible duplicate of [Can we call a Controller's method from a view (as we call from helper ideally)?](http://stackoverflow.com/questions/8906527/can-we-call-a-controllers-method-from-a-view-as-we-call-from-helper-ideally) – lulalala Jan 21 '14 at 06:32

4 Answers4

40

At the top of your controller you can mark the method that you want available to your views as a helper method:

helper_method :course_user_count

Then in your view, you can call course_user_count and store the result.

<% count = course_user_count %>
zelanix
  • 3,326
  • 1
  • 25
  • 35
Keith
  • 686
  • 5
  • 7
  • @Keith a small update it's `helper_method :course_user_count` – Sri Harsha Kappala May 22 '14 at 14:29
  • This answer worked for me on Rails 4.0.0. Thank you very much! – Marty C. Jun 14 '14 at 02:45
  • This answer is totally correct and it worked for me. However, remember the adage "Fat model, skinny controller". Most of the time, putting a helper method on the controller is not the right thing to do. Remember to look at the models you are using in the view and see if any of them would be a better place to put the code you want to execute. – Jason L. Jan 22 '22 at 02:51
9

I don't quite understand what you mean when you say that you have to "call this @count variable" from your view. Are you not setting that variable in your controller? If so, it should automatically be accessible in the associated view. (You don't "call" a variable, you read it or set it.)

Second, your method reads each course's student count and then assigns it to the variable @count. Each time this variable is written to, its previous value is overwritten, so the method as written is useless. I'm not sure what you're trying to do here -- perhaps "initializing" the controller by setting this value in advance for each course?

By convention, a controller's show method shows the information for one line of the associated database. If the aim is to show the course's student count in that view, I would write something like this in app/controllers/course_controller.rb:

class CourseController < ApplicationController

  def show
    @course = Course.find(params[:id]) # Here I assume that the url is .../courses/<id>
    @student_count = @course.students.count
  end

  ...

end

And display the variable's value like this in template app/views/courses/show.html.erb:

<%= @student_count %>

In other words, I wouldn't write a method in the controller to return a course's student count, but instead just pass it as a parameter to the view, just as I would pass anything else the view needs to display -- or at least anything that the view can't access by a very simple operation, a condition not really fulfilled by @course.students.count, but that's a matter of taste.

However, it might make sense to define a method in the controller for values that are more complex to compute and/or are not needed every time the show template is displayed. To make that method callable from your views, the method has to be declared a helper method, as Keith mentioned in his answer. For instance, a method that returns the total student count of all courses in app/controllers/course_controller.rb:

class CourseController < ApplicationController

  helper_method :total_student_count

  def total_student_count
    total_count = 0
    Course.all.each do |c|
      total_count += c.students.count
    end
    total_count
  end

  ...

end

Use the method like this in any template under app/views/courses/ to display the value returned by that method:

<%= total_student_count %>
Teemu Leisti
  • 3,750
  • 2
  • 30
  • 39
1

declare method name as the helper method

In the view call the method as

<% count = course_user_count %>
saran
  • 404
  • 2
  • 4
  • 9
0

Your controller is accessible in your view through the variable:

@controller

which is available by default. I'm talking about the controller associated with that particular view of course.

In your case:

@controller.course_user_count
Miotsu
  • 1,776
  • 18
  • 30