HPJAJ
HPJAJ

Reputation: 1484

How to call a controller method in an associated view file?

I am trying to create a method in a controller file, and then call that method in the index.html.erb view file.

Here are both my index action and my custom method in the controller file:

def index
  @mustdos = current_user.mustdos
end

def calculates_mustdos_days_left
  ((mustdo.created_at + 7.days - Time.now) / ( 60 * 60 * 24)).round
end
helper_method :calculates_mustdos_days_left

And here is the relevant code from my associated my index.html.erb file:

<% @mustdos.each do |mustdo| %>
  <tr id="todo-<%= "#{mustdo.id}" %>">
    <td><%= calculates_mustdos_days_left %></td>
  </tr>
<% end %>

I am getting this error:

NameError in Mustdos#index

And it is referencing this line from my index.html.erb view file

<td><%= calculates_mustdos_days_left %></td>

How can I resolve this? Thanks.

Upvotes: 1

Views: 1158

Answers (3)

Igor Guzak
Igor Guzak

Reputation: 2165

you could try:

helper_method def calculates_mustdos_days_left(mustdo)
  ((mustdo.created_at + 7.days - Time.now) / ( 60 * 60 * 24)).round
end

and then in your view file:

<% @mustdos.each do |mustdo| %>
  <tr id="todo-<%= "#{mustdo.id}" %>">
    <td><%= calculates_mustdos_days_left(mustdo) %></td>
  </tr>
<% end %>

but instead controller methods you should use helper methods, also if your method is more general (related to model) and doesn't depend from view, you could define it in your model as @craig.kaminsky written

Upvotes: 1

xander-miller
xander-miller

Reputation: 529

You can't do it. You can't call methods outside of the controller action you are in in your view. If you have a piece of logic like that you should really try to get it into a model. In this case I would put this method in the mustdo model.

But in those cases where putting the logic into a model does not make sense you can use helper namespaces. It is sort of a miscellaneous drawer for methods that don't quite fit anywhere, like display logic. Helpers go in the app/helpers/ directory. By default there is a helper namespace file in there called application_helper.rb. Any method you put in there will be available in all your controllers and views.

Upvotes: 0

craig.kaminsky
craig.kaminsky

Reputation: 5598

In general, I try to leave my helper methods for when I need them to generate content/output for a view. When I want to calculate and return data regarding a particular Model instance, I either add that code to a Service or the model itself.

app/models/must_do.rb

def days_left
  ((self.created_at + 7.days - Time.now) / ( 60 * 60 * 24)).round
end

Then, in my view, it's easy to access this off the model's instance:

<% @mustdos.each do |mustdo| %>
  <tr id="todo-<%= "#{mustdo.id}" %>">
    <td><%= mustdo.days_left %></td>
  </tr>
<% end %>

For me, this is a cleaner implementation of the desired behavior. Wanted to offer it as an alternative/additional approach to @IS04's answer.

Upvotes: 2

Related Questions