【问题标题】:(undefined method `receipts_for' for nil:NilClass - MailBoxer Gem Rails(未定义的方法 `receipts_for' 用于 nil:NilClass - MailBoxer Gem Rails
【发布时间】:2018-05-28 17:58:57
【问题描述】:

我正在使用mailboxer gem 为我的rails 应用程序在用户之间构建一个消息传递系统。出于某种原因,我收到了这个错误:

(nil:NilClass 的未定义方法 `receipts_for')

也许是因为我应该在我的控制器或mailboxer.rb 中的某个地方定义“receipts_for”?我尝试了一些东西..但不幸的是,它们都没有成功。

这是我的路线.rb:

Rails.application.routes.draw do
  root   'static_pages#home'
  get    '/help',    to: 'static_pages#help'
  get    '/about',   to: 'static_pages#about'
  get    '/contact', to: 'static_pages#contact'
  get    '/signup',  to: 'users#new'
  get    '/login',   to: 'sessions#new'
  get    'search/index'
  post   '/login',   to: 'sessions#create'
  delete '/logout',  to: 'sessions#destroy'
  resources :users do
    member do
      get :following, :followers
    end
  end
  resources :conversations do
    resources :messages
  end
  resources :account_activations, only: [:edit]
  resources :password_resets,     only: [:new, :create, :edit, :update]
  resources :microposts,          only: [:create, :destroy]
  resources :relationships,       only: [:create, :destroy]
  resources :searches
end

这是我的对话控制器:

class ConversationsController < ApplicationController

  def show
    @conversation = current_user.mailbox.conversation.find(params[:id])
  end


  def new
    @recipients = User.find(params[:user_id])
  end

  def create
    recipient = User.find(params[:user_id])
    receipt = current_user.send_message(recipient, params[:body])
    redirect_to conversation_path(receipt.conversation)
  end

end

这是我的messages_controller:

class MessagesController < ApplicationController
  before_action :set_conversation

  def create
    receipt = current_user.send_message(@conversation, body)
    redirect_to receipt.conversation
  end

  private

  def set_conversation
    @conversation = current_user.mailbox.conversations.find(params[:conversation_id])
  end

end

确切地说,我正在构建的消息传递系统是一个消息传递系统,其中“当前用户”可以转到应用程序上任何用户的个人资料页面并通过个人资料页面向他/她发送消息。所以这意味着我正在我的用户模型的 show.html.erb 中渲染对话模型的 show.html.erb。这是两个视图的代码:

show.html.erb - 用户模型:

<% provide(:title, @user.name) %>
<div class="row">
  <aside class="col-md-4">
    <section>
      <h1>
        <%= gravatar_for @user %>
        <%= @user.name %>
      </h1>
    </section>
    <section class="stats">
      <%= render 'shared/stats' %>
    </section>
      <h6>
        <%= @user.gender %>
      </h6>
    <%= render "conversations/conversation" %>
  </aside>
  <div class="col-md-8">
    <%= render 'follow_form' if logged_in? %>
    <% if @user.microposts.any? %>
      <h3>Microposts (<%= @user.microposts.count %>)</h3>
      <ol class="microposts">
        <%= render @microposts %>
      </ol>
      <%= will_paginate @microposts %>
    <% end %>
  </div>
</div>

_conversation.html.erb - 显示对话模型的视图。

<% @conversation.receipts_for(current_user).each do |receipt| %>
    <div>
        <%= receipt.message.body %>
    </div>
<% end %>


<%= form_tag conversation_messages_path(@conversation), method: post do  %>
    <div>
        <%= text_area_tag :body %>
    </div>

    <%= submit_tag %>
<% end %>

那么我该如何为我的邮箱定义“receipts_for”方法呢?还是我的代码有其他问题?

任何帮助将不胜感激!

谢谢!

【问题讨论】:

  • 所以GET /users/:id(即UsersController#show)使用show.html.erb 视图,而该视图使用_conversation.html.erb 部分?但是UsersController#show 没有设置@conversation?顺便说一句,我通常发现使用实例变量将信息导入部分只会导致痛苦和痛苦,当您更明确地了解数据如何移动时,事情会更容易理解。
  • Users 模型的无 show.html 呈现对话控制器的 show.html。就是这样。为什么我需要在 UsersController#show 中设置 @conversation?
  • @muistooshort 标记你
  • 您唯一的receipts_for 调用是部分中的@conversation.receipts_for,我看到的唯一使用该部分的东西是show.html.erb 用于(显然)您的用户。该错误告诉您@conversation 是部分nil。 “用户模型的 show.html 呈现了对话控制器的 show.html”对我来说没有意义;模型不渲染任何东西,控制器做; ConversationsController 中的方法从 app/views/conversations/ 渲染视图,除非您做出特殊安排。

标签: ruby-on-rails ruby ruby-on-rails-4 rubygems mailboxer


【解决方案1】:

我会附上@mu is too short 所说的话。注意整个错误消息很重要。 “nil:NilClass 的未定义方法receipts_for”告诉你receipts_for 方法的接收者是nil。 @conversation.receipts_for(current_user) 看起来是唯一使用 receipts_for 的地方,因此我将通过确保为 @conversation 分配现有 ActiveRecord 支持的对话对象的值来开始调试。

似乎发生了太多事情,所以我不知道如何为您提供快速解决方案。 ConversationsController#show 方法中的赋值,@conversation= current_user.mailbox.conversation.find(params[:id]) 看起来很麻烦。这表明您正在寻找基于属于current_usermailboxconversation,这可能是您想要的(在这种情况下,您需要在您的楷模)。

但是,由于链以conversation.find(params[:id]) 结尾,我猜current_user.mailbox 是不需要的。或者,如果您的 params 实际上没有对话 ID,那么也许这就是您需要关注的内容。

好消息是,如果您将byebug(或binding.pry,取决于您安装的内容)放在show 方法的顶部并在您的视图中,您可能会弄清楚如何定义@conversation部分:

# In the controller:

  def show
    binding.pry
    @conversation = current_user.mailbox.conversation.find(params[:id])
  end


# in the view
<% binding.pry %>

【讨论】:

  • 嗨@Ginnie :) 感谢您的帮助。我正在逐渐尝试了解问题和错误原因。但是您能否详细说明您的意思:“这表明您正在寻找基于属于 current_user 的邮箱的对话,这可能是您想要的(在这种情况下,您的模型需要具有适当的定义的关联)”。我应该在模型中建立什么样的关联?究竟是什么型号?用户模型?还是对话模型?对不起,如果我没有得到这个!谢谢你对我的耐心。我还是个新手!
  • 发表评论后,我遇到了一个 Go Rails 插曲,它实现了相同的邮箱 gem。作者有一个指向源代码的链接,因此您可以看到他们是如何设置所有内容的。他们使用与你相同的赋值,所以你可能会忽略我关于这个特定问题的繁琐赋值的建议。集数:gorails.com/episodes/in-app-messaging-between-users GitHub 上的代码:github.com/gorails-screencasts/gorails-episode-105/blob/master/…
  • 如果您是 Rails 新手,我会花时间了解如何设置 has_many 和 belongs_to 关联,并看看在正确设置这些关联后您会获得哪些方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多