Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails Method not available in View

I get this strange error. I have defined a method for my model

    class Rating < ActiveRecord::Base

  [...]

  belongs_to :user
  belongs_to :movie

  [...]

  def to_text
    texto = case self.grade
            when 0..1 then "horrible"
            when 2..3 then "bad"
            when 4..5 then "not bad"
            when 6..7 then "good"
            when 8..9 then "very good"
            when 10 then "master piece"
            end
  end
end

Then, on my controller, I define this instance:

@[email protected](:user_id => current_user)

And it does find it, so it works. But then, when I call the method, or a property like

<%= @current_user_rating.grade %>
<%= @current_user_rating.to_text %>

I get this error

undefined method `grade' for []:ActiveRecord::Relation
undefined method `to_text' for []:ActiveRecord::Relation

Why the variable not behaving as an instance with appropriate attributes and methods but as a Relation?

It does work on the Console, but not on the server...

like image 219
brunosan Avatar asked Feb 25 '23 07:02

brunosan


2 Answers

since a movie has multiple ratings, @current_user_rating is a collection of them, even if there is one. you should be able to get rid of the errors by calling your methods like this:

<% @current_user_rating.each do |rating| %>
  <%= rating.grade %>
  <%= rating.to_text %>
<% end %>
like image 62
GSto Avatar answered Mar 08 '23 11:03

GSto


When you call where it doesn't actually query the database, it creates an object which can be converted and run on the database. This is useful for further modifying the query before it is run.

Typically a further call to first or all is added to actually execute the query and get the result. (Note that this might be done automatically if you call where in the rails console, so that the result can be printed)

In your case, it looks like a user is expected to rate a movie no more than once, so the following seems appropriate:

@[email protected](:user_id => current_user).first

EDIT: Actually I think GSto is correct, what I wrote above does not look like the reason for your failure. The error message is actually complaining that the methods you are trying to call aren't valid to be called on an Array of objects. In this case, first is simply selecting the first result and ignoring any others.

It would be good to double-check if you have any movies for which a single user has multiple ratings. In fact, I'd recommend adding a validation to ensure that this is not allowed, if it is not intended.

like image 27
Mike Tunnicliffe Avatar answered Mar 08 '23 10:03

Mike Tunnicliffe