Rails4动作控制器 - 未定义的方法'长度'为零:NilClass

时间:2016-11-13 07:49:28

标签: ruby-on-rails ruby activerecord

我正在为我的一个项目从零开始构建一个消息传递系统。 一切都运作良好,但我发现了以下错误:NoMethodError in MessagesController#index后跟undefined method 'length' for nil:NilClass。 不幸的是,我无法找到与我的案例相符的任何答案。

我给你conversations_controller.rbmessages_controller.rb,模型和路线(以及日志):

conversations_controller.rb

class ConversationsController < ApplicationController
  before_action :authenticate_user!

  def index
    @users = User.all
    @conversations = Conversation.all
  end

  def create
    if Conversation.between(params[:sender_id], params[:recipient_id]).present?
      @conversation = Conversation.between(params[:sender_id], params[:recipient_id]).first
    else
      @conversation = Conversation.create!(conversation_params)
    end
    redirect_to conversation_messages_path(@conversation)
  end

  private

  def conversation_params
    params.permit(:sender_id, :recipient_id)
  end

end

messages_controller.rb:

class MessagesController < ApplicationController

  def index
    if @messages.length > 10
      @over_ten = true
      @messages = @messages[-10..-1]
    end
    if params[:m]
      @over_ten = false
      @messages = @conversation.messages
    end
    if @messages.last
      if @messages.last.user_id != current_user.id
        @messages.last.read = true;
      end
    end
    @message = @conversation.messages.new
  end

  def new
    @message = @conversation.messages.new
  end

  def create
    @message = @conversation.messages.new(message_params)
    if @message.save
      redirect_to conversation_messages_path(@conversation)
    end
  end

  private

  def message_params
    params.require(:message).permit(:body, :user_id)
  end
end

conversation.rb:

class Conversation < ActiveRecord::Base
  belongs_to :sender, foreign_key: :sender_id, class_name: 'User'
  belongs_to :recipient, foreign_key: :recipient_id, class_name: 'User'

  has_many :messages, dependent: :destroy

  validates_uniqueness_of :sender_id, scope: :recipient_id

  scope :between, -> (sender_id,recipient_id) do
    where("(conversations.sender_id = ? AND conversations.recipient_id = ?)
            OR (conversations.sender_id = ? AND conversations.recipient_id = ?)",
            sender_id,recipient_id, recipient_id,sender_id)
    end
end

message.rb:

class Message < ActiveRecord::Base
  belongs_to :conversation
  belongs_to :user

  validates_presence_of :body, :conversation_id, :user_id

  def message_time
    created_at.strftime("%m/%d/%y at %l:%M %p")
  end
end

Routes.rb:

Rails.application.routes.draw do

  get 'messages/index'

  get 'messages/new'

  get 'conversations/index'

  get 'dashboard/index'

  get 'dashboard/trips'

  get 'dashboard/messages'

  get "welcome/index"

  resources :conversations do
    resources :messages
  end

  devise_for :users

  authenticated :users do
    root to: 'dashboard#index', as: :authenticated_root
  end

  root "welcome#index"
end

这里是日志:

Started GET "/conversations/5/messages" for ::1 at 2016-11-13 16:45:38 +1030
Processing by MessagesController#index as HTML
  Parameters: {"conversation_id"=>"5"}
Completed 500 Internal Server Error in 5ms (ActiveRecord: 0.0ms)

NoMethodError (undefined method `length' for nil:NilClass):
  app/controllers/messages_controller.rb:4:in `index'


  Rendered /Users/JUSTINE/.rvm/gems/ruby-2.3.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/_source.erb (3.7ms)
  Rendered /Users/JUSTINE/.rvm/gems/ruby-2.3.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.1ms)
  Rendered /Users/JUSTINE/.rvm/gems/ruby-2.3.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.7ms)
  Rendered /Users/JUSTINE/.rvm/gems/ruby-2.3.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (53.1ms)
  Rendered /Users/JUSTINE/.rvm/gems/ruby-2.3.0/gems/web-console-2.3.0/lib/web_console/templates/_markup.html.erb (0.5ms)
  Rendered /Users/JUSTINE/.rvm/gems/ruby-2.3.0/gems/web-console-2.3.0/lib/web_console/templates/_inner_console_markup.html.erb within layouts/inlined_string (0.3ms)
  Rendered /Users/JUSTINE/.rvm/gems/ruby-2.3.0/gems/web-console-2.3.0/lib/web_console/templates/_prompt_box_markup.html.erb within layouts/inlined_string (0.4ms)
  Rendered /Users/JUSTINE/.rvm/gems/ruby-2.3.0/gems/web-console-2.3.0/lib/web_console/templates/style.css.erb within layouts/inlined_string (0.3ms)
  Rendered /Users/JUSTINE/.rvm/gems/ruby-2.3.0/gems/web-console-2.3.0/lib/web_console/templates/console.js.erb within layouts/javascript (40.4ms)
  Rendered /Users/JUSTINE/.rvm/gems/ruby-2.3.0/gems/web-console-2.3.0/lib/web_console/templates/main.js.erb within layouts/javascript (0.4ms)
  Rendered /Users/JUSTINE/.rvm/gems/ruby-2.3.0/gems/web-console-2.3.0/lib/web_console/templates/error_page.js.erb within layouts/javascript (0.7ms)
  Rendered /Users/JUSTINE/.rvm/gems/ruby-2.3.0/gems/web-console-2.3.0/lib/web_console/templates/index.html.erb (91.6ms)

我希望它对您有所帮助,我们将能够找到答案:)

干杯

2 个答案:

答案 0 :(得分:0)

未设置@messages中的MessagesController实例变量。您需要先将其初始化为current_user.messages

  def index
    @messages = current_user.messages # or something like this

    if @messages.length > 10
      @over_ten = true
      # ...

答案 1 :(得分:0)

每当您在格式化的ruby中看到任何错误消息时:

#chickcontainer img{
    position:relative;
    width:30%;
    height:30%;
    display:inline-block;
    margin-left:2%;
    border-radius:100%;
    border: solid .5px;

}

.overlay{
    visibility:hidden;
    position:absolute;
    width:20%;
    height:90%;
    top:12%;
    left:7%;
    z-index:0;
}

#chickcontainer img:hover .overlay{
    visibility:visible;
    z-index:100;
}

你被告知你正试图在零物体上调用某物,所以你应该关注为什么那个物体为零。您还会在日志中告知错误发生的位置:

undefined method 'method_name' for nil:NilClass

就是这一行:

app/controllers/messages_controller.rb:4:in `index'

所以@messages是零,在这种情况下它没有,因为它还没有被宣布:

if块之前的

执行以下操作:

if @messages.length > 10