【问题标题】:Ruby on Rails - undefined method - Model can't be accessed by ControllerRuby on Rails - 未定义的方法 - 控制器无法访问模型
【发布时间】:2017-03-28 14:20:05
【问题描述】:

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

我试图让我的用户出现在排名表中,但我收到一条错误消息,指出我的 LeaguesController 文件中有一个未定义的方法。我为我的控制器文件尝试了以下类名 - LeaguesController

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)

如果您想查看任何其他文件,请在 cmets 中告诉我。对此有任何帮助/建议将不胜感激。感谢您的宝贵时间。

【问题讨论】:

  • 请发布您的错误信息(日志)。
  • @HolgerFrohloff 糟糕,刚刚添加了日志
  • 因此,我们不会将“SOLVED”放在问题中。相反,我们选择提供解决方案的答案来标记它。此外,不需要问候、告别和签名,因此应删除最后一行。请记住,SO 不是讨论列表,它更像是一本参考书,更像是一本百科全书或食谱,其中简洁明了更重要。您的问题是一个页面的开场问题,该页面为将来寻找类似解决方案的其他人提供了该问题的解决方案。

标签: ruby-on-rails ruby model-view-controller controller cloud9-ide


【解决方案1】:

我看不到您的视图文件,但我假设您在每个用户或他们的个人资料上调用 .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 %>

【讨论】:

  • 谢谢@Mark,尽管我有另一个 index.html.erb 文件显示所有用户的列表(不是排名表页面),但它没有“如果用户” .avatar' 并且该页面工作正常。我也尝试过完全删除头像行,我得到的以下错误是关于 first_name 所以我认为这是模型/控制器的问题?
  • 问题将持续存在。您需要确保您调用该方法的记录/对象确实存在。这就是马克在这里试图解释的。 :)
  • 尝试更改我的编辑中的两行,它应该可以工作 - 抱歉,我能想到的就这些
  • @Mark 我已经删除了 HTML 的负载,只留下了头像行,它现在出现了。非常感谢你的帮助。这让我发疯了一段时间。将为其他对象添加相同的内容。
  • 乐于助人!有时它是反直觉的,但 95% 的错误消息会指出哪里出了问题或指出正确的方向(在这种情况下为头像)
【解决方案2】:

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

具体来说:你使用了user.profile.avataruser记录在那里,但是当你在这个user上调用.profile时,你会收到nil。 您可以确保在调用方法之前检查记录是否可用。 this other answer

中给出了如何做到这一点的想法

您是否发现我的控制器/模型有任何问题可以解释为什么这些记录不可用?

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

【讨论】:

  • 感谢 Holger,请参阅我对 Mark 的回复。你能看到我的控制器/模型有什么问题,可以解释为什么这些记录不可用吗?
猜你喜欢
  • 2012-07-18
  • 2012-08-14
  • 2015-06-14
  • 2023-03-07
  • 2011-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多