Search code examples
ruby-on-railsformsactionviewupdate-attributes

ActionView::Template::Error (undefined method `to_model' for true:TrueClass for Update Attribute Method


So this is really a continuation of a previous coding issue which can be found here. The previous question asked what was wrong with the back-end. Now however I'm having issues with the front-end code.

I'm trying to create a button that when clicked will update the relationship to favorited, and unfavorited if already favorited.

partials/_favorite.html.erb

<%= form_tag current_user.favorite(@user), remote: true do |f| %>     # partials/_favorite.html.erb:1
    <div>
        <%= hidden_field_tag :followed_id, @user.id %>
    </div>
    <%= button_tag(class: "d-block mx-auto btn btn-warning") do %>
        <%= icon('far', 'star') %>
    <% end %>
<% end %>

forms/_favorite.html.erb

<% unless current_user?(@user) %>
    <div id="follow_form">
        <% if current_user.favorited?(@user) %>
            <%= render 'partials/unfavorite' %>
        <% else %>
            <%= render 'partials/favorite' %>     # forms/_favorite.html.erb:1
        <% end %>
    </div>
<% end %>

_stats.html.erb

<% @user ||= current_user %>

<div class="row">
    <div class="col-4 text-center">
        <%= link_to following_user_path(@user) do %>
            <b>Following</b><br>
            <%= @user.following.count %>
        <% end %>
    </div>
    <div class="col-4 text-center">
        <%= link_to followers_user_path(@user) do %>
            <b>Followers</b><br>
            <%= @user.followers.count %>
        <% end %>
    </div>
    <div class="col-4">
        <%= render 'forms/follow', followed_id: @user.id %>
        <%= render 'forms/favorite', followed_id: @user.id if current_user.following?(@user) %>     # _stats.html.erb:18
    </div>
</div>

I've been working on this same function interface for roughly a week and I haven't been able to successfully implement it. The favorite and unfavorite methods work successfully thanks to the solution in the previous question. The testing suite reveals no errors.

I don't understand the error that I'm receiving which is a major part of why I haven't been able to solve the coding issue. I would greatly appreciate some assistance.

The error I'm encountering is:

ActionView::Template::Error (undefined method `to_model' for true:TrueClass
Did you mean?  to_yaml):
    1: <%= form_tag current_user.favorite(@user), remote: true do |f| %>
    2:  <div>
    3:          <%= hidden_field_tag :followed_id, @user.id %>
    4:  </div>

app/views/partials/_favorite.html.erb:1:in `_app_views_partials__favorite_html_erb__875601414_141134960'
app/views/forms/_favorite.html.erb:6:in `_app_views_forms__favorite_html_erb__719356774_141387060'
app/views/partials/_stats.html.erb:18:in `_app_views_partials__stats_html_erb__832871257_32744880'
app/views/users/show.html.erb:13:in `_app_views_users_show_html_erb__718176203_36043580'

Solution

  • I finally solved the issue I've been having with this update relationship attribute.

    First, I had to determine what the error I was receiving meant. For those who are still relatively new to Rails, "undefined method `to_model' for true:TrueClass" means that you are attempting to create a conditional statement without a conditional.

    The statements: current_user.favorite(@user) and current_user.unfavorite(@user) were returning true which the program didn't know how to evaluate. Therefore I had to change:

    partials/_favorite.html.erb

    <%= form_tag current_user.favorite(@user), remote: true do |f| %>
        <div>
            <%= hidden_field_tag :followed_id, @user.id %>
        </div>
        <%= button_tag(class: "d-block mx-auto btn btn-warning") do %>
            <%= icon('far', 'star') %>
        <% end %>
    <% end %>
    

    to...

    <%= link_to favorite_relationship_path(current_user.active_relationships.find_by(followed_id: @user.id)), method: :put, remote: true do %>
        <%= button_tag(class: "d-inline btn btn-warning") do %>
            <%= icon('far', 'star') %>
        <% end %>
    <% end %>
    

    and similarly with partials/_unfavorite.html.erb

    This also meant that I needed to introduce subsequent actions in the relationships controller

    Relationships_controller.rb

      def favorite
        @user = Relationship.find(params[:id]).followed
        current_user.favorite(@user)
        respond_to do |format|
          # Handle a Successful Unfollow
          format.html
          format.js
        end
      end
    
      def unfavorite
        @user = Relationship.find(params[:id]).followed
        current_user.unfavorite(@user)
        respond_to do |format|
          # Handle a Successful Unfollow
          format.html
          format.js
        end
      end
    

    These controller actions would then loop back to my user model methods:

    User.rb

    def favorite(other_user)
        active_relationships.find_by(followed_id: other_user.id).favorite
    end
    
    def unfavorite(other_user)
        active_relationships.find_by(followed_id: other_user.id).unfavorite
    end
    

    which would then in turn trigger the relationship model to update the attributes successfully:

    Relationship.rb

    def favorite
        update_attribute(:favorited, true)
    end
    
    def unfavorite
        update_attribute(:favorited, false)
    end