Ruby on Rails - 未定义的方法 - 控制器无法访问模型

Ruby on Rails - undefined method - Model can't be accessed by Controller

已解决 - 我在显示个人资料头像之前在 HTML.erb 中添加了一个 if 语句,它现在出现了。感谢 Mark 和 Holger 的帮助。

我试图让我的用户出现在联盟中 table 但我收到一条错误消息,指出我的 LeaguesController 文件中有一个未定义的方法。我已经为我的控制器文件尝试了以下 class 名称 - LeaguesController < Application Controller 和 LeaguesController < UsersController (我知道该方法已在此 class 中定义,将 post 都在下面) . 'index' 匹配 html.erb 文件名。

LeaguesController(我已经尝试 User.includes(:profile).order(etc) 但仍然没有获取用户字段)

class LeaguesController < ApplicationController
  def index
    @LMSusers = User.order('last_sign_in_at DESC')
    @MVPusers = User.order('sign_in_count DESC')
    @LMSuser_position = User.order('last_sign_in_at DESC').find_index(current_user)
    @MVPuser_position = User.order('sign_in_count DESC').find_index(current_user)
  end
end

用户模型文件

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  # Association - Ruby Documentation       
  belongs_to :plan
  has_one :profile
end

用户控制器

class UsersController < ApplicationController
  before_action :authenticate_user!


  def index
    @users = User.includes(:profile)
  end

    # Use rails routes in console to find what URL path should be used and 
    # what dynamic ids need to be included. Use params in relevant controller file
    # to include the paramater.

  # GET to /users/:id
  def show 
    # "User" is refering to model with same name -> user.rb
    @user = User.find( params[:id] )
  end

end

真正奇怪的是这段代码过去工作正常。在它停止工作之前,我将它与之前的提交进行了比较,它们似乎完美匹配。当我克隆提交时,它也工作正常,所以我真的不知道从哪里开始寻找这个错误。我没有联赛的模型文件,但我从来没有做过,而且它曾经工作得很好。我从未将联赛纳入任何 belongs_to/has_many 协会,但同样,它曾经工作得很好......

这里也是路由文件。

Routes.rb

Rails.application.routes.draw do
    root to: 'pages#home'
    devise_for :users, controllers: { registrations: 'users/registrations' }
    resources :users do
        # Singular resource and profile because requiring only one resource and profile per user
       resource :profile
    end
    resources :leagues
    get 'about', to: 'pages#about'
    resources :contacts, only: :create
    get 'contact-us', to: 'contacts#new', as: 'new_contact'

    # Nested Resources Documentation

end

HTML.erb 文件

<div>
  <h1 class="text-center">The Leaderboard</h1></br>
  <p class="text-center">Check how you compare to the top 5 in the community.</p></br>
</div>

<div class="container">
  <div class="row">
    <div class="col-md-6">
      <div>
        <table class="table">
          <tr>
            <th class="league-header" colspan="6">Last Man Standing</th>
          </tr>
          <tr class="row-header">
            <th>Position</th>
            <th>Name</th>
            <th class="left-column">Job Title</th>
            <th class="left-column">Last Logged In</th>
          </tr>
          <% @LMSusers.each_with_index do |user, index| %>
            <% if index < 5 %>
              <tr class="tr">
                <td style="padding-top: 20px;"><%= index+1 %></td>
                <td class="left-column"><%= link_to user do %><%= image_tag user.profile.avatar.url, class: 'sml-avatar-show-img' %><% end %> <%= link_to user do %><%= user.profile.first_name %> <%= user.profile.last_name %><% end %></td>
                <td style="padding-top: 20px;" class="left-column"><%= user.profile.job_title %></td>
                <td style="padding-top: 20px;" class="left-column"><%= user.last_sign_in_at.strftime("%d/%m/%Y") %></td>
              </tr>
            <% end %>  
          <% end %>
          <% if user_signed_in? %>
            <% if current_user.profile %>
              <tr class="tr user-tr">
                <td style="padding-top: 20px;" ><%= @LMSuser_position + 1 %></td>
                <td class="left-column"><%= link_to user_path(current_user.id) do %><%= image_tag current_user.profile.avatar.url, class: 'sml-avatar-show-img' %><% end %> <%= link_to user_path(current_user.id) do %><%= current_user.profile.first_name %> <%= current_user.profile.last_name %><% end %></td>
                <td style="padding-top: 20px;" class="left-column"><%= current_user.profile.job_title %></td>
                <td style="padding-top: 20px;" class="left-column"><%= current_user.last_sign_in_at.strftime("%d/%m/%Y") %></td>
              </tr>
            <% end %>
          <% end %>
        </table>
      </div>
    </div>
    <div class="col-md-6">
      <div>
        <table class="table">
          <tr>
            <th class="league-header" colspan="6">MVP</th>
          </tr>
          <tr class="row-header">
            <th>Position</th>
            <th>Name</th>
            <th class="left-column">Job Title</th>
            <th class="left-column">Number of Logins</th>
          </tr>
          <% @MVPusers.each_with_index do |user, index| %>
            <% if index < 5 %>
              <tr class="tr">
                <td style="padding-top: 20px;"><%= index + 1 %></td>
                <td class="left-column"><%= link_to user do %><%= image_tag user.profile.avatar.url, class: 'sml-avatar-show-img' %><% end %> <%= link_to user do %><%= user.profile.first_name %> <%= user.profile.last_name %><% end %></td>
                <td style="padding-top: 20px;" class="left-column"><%= user.profile.job_title %></td>
                <td style="padding-top: 20px;" class="left-column"><%= user.sign_in_count %></td>
              </tr>
            <% end %>
          <% end %>
          <% if user_signed_in? %>
            <% if current_user.profile %>
              <tr class="tr user-tr">
                <td style="padding-top: 20px;" ><%= @MVPuser_position + 1 %></td>
                <td class="left-column"><%= link_to user_path(current_user.id) do %><%= image_tag current_user.profile.avatar.url, class: 'sml-avatar-show-img' %><% end %> <%= link_to user_path(current_user.id) do %><%= current_user.profile.first_name %> <%= current_user.profile.last_name %><% end %></td>
                <td style="padding-top: 20px;" class="left-column"><%= current_user.profile.job_title %></td>
                <td style="padding-top: 20px;" class="left-column"><%= current_user.sign_in_count %></td>
              </tr>
            <% end %>
          <% end %>
        </table>
      </div>
    </div>
  </div>
</div>

错误日志

Started GET "/leagues" for xx.xxx.xx.xxx at 2017-03-28 14:23:54 +0000
Cannot render console from xx.xxx.xx.xxx! Allowed networks: xxx.x.x.x, ::1, xxx.x.x.x/xxx.xxx.xxx.xxx
Processing by LeaguesController#index as HTML
  User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ?  [["id", 3], ["LIMIT", 1]]
  User Load (0.3ms)  SELECT "users".* FROM "users" ORDER BY last_sign_in_at DESC
  Profile Load (0.2ms)  SELECT "profiles".* FROM "profiles" WHERE "profiles"."user_id" IN (9, 3, 8, 7, 6, 5, 2, 4, 1)
  User Load (0.3ms)  SELECT "users".* FROM "users" ORDER BY sign_in_count DESC
  Profile Load (0.2ms)  SELECT "profiles".* FROM "profiles" WHERE "profiles"."user_id" IN (3, 1, 2, 5, 7, 4, 6, 8, 9)
  Rendering leagues/index.html.erb within layouts/application
  CACHE (0.0ms)  SELECT "users".* FROM "users" ORDER BY last_sign_in_at DESC
  CACHE (0.0ms)  SELECT "profiles".* FROM "profiles" WHERE "profiles"."user_id" IN (9, 3, 8, 7, 6, 5, 2, 4, 1)
  Rendered leagues/index.html.erb within layouts/application (76.6ms)
Completed 500 Internal Server Error in 88ms (ActiveRecord: 1.5ms)



ActionView::Template::Error (undefined method `avatar' for nil:NilClass):
    21:             <% if index < 5 %>
    22:               <tr class="tr">
    23:                 <td style="padding-top: 20px;"><%= index+1 %></td>
    24:                 <td class="left-column"><%= link_to user do %><%= image_tag user.profile.avatar.url, class: 'sml-avatar-show-img' %><% end %> <%= link_to user do %><%= user.profile.first_name %> <%= user.profile.last_name %><% end %></td>
    25:                 <td style="padding-top: 20px;" class="left-column"><%= user.profile.job_title %></td>
    26:                 <td style="padding-top: 20px;" class="left-column"><%= user.last_sign_in_at.strftime("%d/%m/%Y") %></td>
    27:               </tr>

app/views/leagues/index.html.erb:24:in `block (2 levels) in _app_views_leagues_index_html_erb___1987220472087352031_70206048257300'
app/views/leagues/index.html.erb:24:in `block in _app_views_leagues_index_html_erb___1987220472087352031_70206048257300'
app/views/leagues/index.html.erb:20:in `each_with_index'
app/views/leagues/index.html.erb:20:in `_app_views_leagues_index_html_erb___1987220472087352031_70206048257300'
  Rendering /usr/local/rvm/gems/ruby-2.3.0@saasapp/gems/actionpack-5.0.0/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb within rescues/layout
  Rendering /usr/local/rvm/gems/ruby-2.3.0@saasapp/gems/actionpack-5.0.0/lib/action_dispatch/middleware/templates/rescues/_source.html.erb
  Rendered /usr/local/rvm/gems/ruby-2.3.0@saasapp/gems/actionpack-5.0.0/lib/action_dispatch/middleware/templates/rescues/_source.html.erb (7.2ms)
  Rendering /usr/local/rvm/gems/ruby-2.3.0@saasapp/gems/actionpack-5.0.0/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb
  Rendered /usr/local/rvm/gems/ruby-2.3.0@saasapp/gems/actionpack-5.0.0/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.7ms)
  Rendering /usr/local/rvm/gems/ruby-2.3.0@saasapp/gems/actionpack-5.0.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
  Rendered /usr/local/rvm/gems/ruby-2.3.0@saasapp/gems/actionpack-5.0.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.4ms)
  Rendered /usr/local/rvm/gems/ruby-2.3.0@saasapp/gems/actionpack-5.0.0/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb within rescues/layout (38.7ms)

如果您想查看任何其他文件,请在评论中告诉我。对此表示感谢 help/advice。谢谢你的时间。

您收到了常见的 for nil:NilClass 错误。您在索引视图中有一个列表,您尝试在其中显示记录的属性。 您可以通过在记录上调用它们的 getter 方法来访问这些属性。这里唯一的问题是,您的记录值是 nil。暂无记录

具体来说:您使用了 user.profile.avatar user 记录在那里,但是当您在此 user 上调用 .profile 时,您收到 nil。 在调用方法之前,您可以确保检查记录是否可用。

中给出了如何做的想法

Can you see any issue with my controller/model which might explain why these records aren't available?

您的 LeaguesController 加载了 User 条记录。但是您可以在您的视图中访问 users 的个人资料。在访问它们之前,您需要确保您的 User 具有关联的 profile

我看不到你的视图文件,但我假设你在每个用户或他们的个人资料上调用 .avatar?

如果您将 user.avatar 或 user.profile.avatar 更改为:

user.avatar if user.avatar

user.profile.avatar if user.profile && user.profile.avatar

那么你应该清除你的错误,只收到一个空白区域,他们的头像应该在这个地方。

编辑:查看视图文件后,这两行之一:

<%= image_tag user.profile.avatar.url, class: 'sml-avatar-show-img' %>

<%= image_tag current_user.profile.avatar.url, class: 'sml-avatar-show-img' %>

显然是在抛出错误。将它们更改为:

<%= (image_tag user.profile.avatar.url, class: 'sml-avatar-show-img') if user.profile && user.profile.avatar %>

<%= (image_tag current_user.profile.avatar.url, class: 'sml-avatar-show-img') if current_user && current_user.profile && current_user.profile.avatar %>