2

我得到一个 NoMethodError undefined method `questions' for nil:NilClass。它指向行上的创建动作@question = @conversation.questions.build(params[:question])

问题控制器:

  respond_to :js, :html

   def index
      @questions = Question.all
      respond_with(@questions)
  end

  def show
    @question = Question.find(params[:id])
    @questions = Question.order("created_at DESC")
    respond_with(@questions)
  end

  def new
    @question = Question.new
    respond_with(@question)
  end

  def create
      @question = @conversation.questions.build(params[:question])
      if @question.save
        @message = current_user.messages.new(:subject => "You have a question from #{@question.sender_id}",
                               :notification_id => @question.sender_id,
                               :receiver_id => @question.recipient_id,
                               :body => @question.question)

        @question.message = @message
        @question.save
        redirect_to questions_path, notice: 'Your question was saved successfully. Thanks!'
      else
        render :new, alert: 'Sorry. There was a problem saving your question.'
      end
    end
  end

对话控制器:

       helper_method :mailbox, :conversation
        before_filter :conversation, only: :show

     def index
        @conversations ||= current_user.mailbox.inbox.all
        end

      def reply
        current_user.reply_to_conversation(conversation, *message_params(:body, :subject))
        redirect_to conversation
      end

      def trash_folder
        @trash ||= current_user.mailbox.trash.all 
        end

      def trash
        conversation.move_to_trash(current_user)
        redirect_to :conversations
        end

      def untrash
        conversation.untrash(current_user)
        redirect_to :conversations
        end

        def empty_trash
          current_user.mailbox.trash.each do |conversation|    conversation.receipts_for(current_user).update_all(:deleted => true)
          end
         redirect_to :conversations
        end
      end

  private

  def mailbox
   @mailbox ||= current_user.mailbox
  end

  def conversation
   @conversation ||= mailbox.conversations.find(params[:id])
  end

  def conversation_params(*keys)
   fetch_params(:conversation, *keys)
  end

  def message_params(*keys)
   fetch_params(:message, *keys)
  end

  def fetch_params(key, *subkeys)
   params[key].instance_eval do
     case subkeys.size
     when 0 then self
     when 1 then self[subkeys.first]
     else subkeys.map{|k| self[k] }
     end
   end
  end
end

消息控制器:

 def index
      redirect_to conversations_path(:box => @box)
    end

  # GET /message/new
  def new
    @message = current_user.messages.new
  end

   # POST /message/create
  def create
    @recipient = User.find(params[:user])
    current_user.send_message(@recipient, params[:body], params[:subject])
    flash[:notice] = "Message has been sent!"
    redirect_to :conversations
  end

问题模型:

  attr_accessible :answer, :question, :sender_id, :recipient_id
  belongs_to :user

  belongs_to :sender,
    :class_name => 'User',
    :foreign_key => 'sender_id'
    belongs_to :recipient,
    :class_name => 'User',
    :foreign_key => 'recipient_id'

    belongs_to :message

end

用户型号:

 acts_as_messageable
  has_many :notifications
  has_many :questions, foreign_key: :recipient_id
  has_many :sent_questions, class_name: 'Question', foreign_key: :sender_id


    def mailboxer_email(object)
        if self.no_email
          email
        else
            nil
        end
    end
end

开发日志:

Started POST "/questions" for 127.0.0.1 at 2014-05-29 12:32:46 -0400
Processing by QuestionsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"YWtv+TixScaYsXpJ6F47uBHkNvcruyHV7cyOtU6pWnQ=", "question"=>{"question"=>"This question should have an conversation id", "sender_id"=>"2", "recipient_id"=>"1"}, "commit"=>"Add Question"}
  User Load (0.3ms)  SELECT `users`.* FROM `users` WHERE `users`.`auth_token` = 'Mqy5_1kyb4hAsrmB9Q0fug' LIMIT 1
   (0.2ms)  BEGIN
  SQL (0.4ms)  INSERT INTO `questions` (`created_at`, `question`, `recipient_id`, `sender_id`, `updated_at`) VALUES ('2014-05-29 16:32:47', 'This question should have an conversation id', 1, 2, '2014-05-29 16:32:47')
   (0.5ms)  COMMIT
WARNING: Can't mass-assign protected attributes for Message: notification_id, reciver_id
    app/controllers/questions_controller.rb:23:in `create'
    app/controllers/application_controller.rb:13:in `user_time_zone'
   (0.2ms)  BEGIN
  User Load (0.5ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 ORDER BY `users`.`id` ASC LIMIT 1
  SQL (0.3ms)  INSERT INTO `notifications` (`body`, `created_at`, `sender_id`, `sender_type`, `subject`, `type`, `updated_at`) VALUES ('This question should have an conversation id', '2014-05-29 16:32:47', 2, 'User', 'You have a question from 2', 'Message', '2014-05-29 16:32:47')
  SQL (0.3ms)  UPDATE `questions` SET `message_id` = 164, `updated_at` = '2014-05-29 16:32:47' WHERE `questions`.`id` = 135
   (0.5ms)  COMMIT
Redirected to http://localhost:3000/questions
Completed 302 Found in 308ms (ActiveRecord: 10.2ms)

此新代码阻止在“问题”表中创建问题。我对代码进行了更改,因为我有问题提交到数据库,但它没有conversation_id使用 Notifications 表中的邮箱 gem 创建一个。下面是在 Questions 表中创建问题的原始代码,但具有NULL.conversation_id

def create
    @question = Question.new(params[:question])
    if @question.save
      @message = current_user.messages.new(:subject => "You have a question from #{@question.sender_id}",
                             :notification_id => @question.sender_id,
                             :reciver_id => @question.recipient_id,
                             :body => @question.question)

      @question.message = @message
      @question.save
      redirect_to questions_path, notice: 'Your question was saved successfully. Thanks!'
    else
      render :new, alert: 'Sorry. There was a problem saving your question.'
    end
  end

所以我需要帮助来修复未定义的方法并将问题提交到带有conversation_id. 我需要该conversation_id集合,以便可以将问题发送到收件人收件箱(这是用户回答问题的地方)。

4

5 回答 5

5

你的@conversation变量永远不会被设置为任何东西,所以它是零。您需要通过将其设置为Converation.new或从数据库中检索对话来将其初始化为某些内容(在这种情况下,这似乎是您想要做的)。

于 2014-04-19T00:29:20.380 回答
0

你有一个@conversationnil你的create行动中有价值的QuestionsController,因为它没有被设置为空。试试这样

def create
    @conversation = Conversation.find(params[:id])
    @question = @conversation.questions.build(params[:question])
    if @question.save
      #scoping to the current user is the right thing to do here
      @message = current_user.messages.new(:subject => "You have a question from #{@question.sender_id}",
                             #Original code :sender_id
                             :notification_id => @question.sender_id,
                             #Original code :recipient_id
                             :receiver_id => @question.recipient_id,
                             :conversation_id => @cnversation.id
                             :body => @question.question)

      @question.message = @message
      @question.save
      redirect_to questions_path, notice: 'Your question was saved successfully. Thanks!'
    else
      render :new, alert: 'Sorry. There was a problem saving your question.'
    end
  end

希望能帮助到你!

更新

我相信您应该有一个Conversation模型来关联模型。通过生成此查询来Question创建模型Conversation

rails g model Conversation

has_many questionsConversation模型添加关系

Class Conversation < ActiveRecord::Base

has_many :questions

end

而且你应该belongs_to conversation在你的Question模型中添加一个。

尝试更新您的Question模型

Class Question < ActiveRecord::Base

attr_accessible :answer, :question, :sender_id, :recipient_id

belongs_to :user

belongs_to :sender,:class_name => 'User',:foreign_key => 'sender_id'

belongs_to :recipient,:class_name => 'User',:foreign_key => 'recipient_id'

belongs_to :message

belongs_to :conversation

end
于 2014-04-19T06:05:23.470 回答
0

为什么不在before_create模型中使用回调:

#app/controllers/conversations_controller.rb
Class ConversationsController < ActiveRecord::Base
    def create
         @conversation = Conversation.new(conversation_params)
         @conversation.save
    end

    private

    def conversation_params
        params.require(:conversation).permit(:conversation, :params, questions: [])
    end
end


#app/models/conversation.rb
Class Conversation < ActiveRecord::Base
    before_create :build_questions

    private
    def build_questions
         self.questions.build
    end
end
于 2014-04-19T08:46:14.767 回答
0

正如其他人所说,错误是由于根本没有设置@conversation变量造成的。

但是,我相信到目前为止回答过的人都没有意识到这是宝石Conversation内部的模型: . 对话实例可从调用结果中获得。你不得不说:mailboxerMailboxer::Conversationsend_message

receipt = send_message ....
conversation = receipt.conversation
# Now you can save the conversation of this message 
# in some useful place so it can be found later.

可以进行对话的其他地方位于messageable. 我认为这是您的User模型,显示为current_user.

您可以通过以下方式获取当前用户的所有对话

current_user.mailbox.conversations

您可以通过选择单个消息队列来执行一些过滤,例如:

current_user.mailbox.inbox

当然,您可能希望获得最后一次对话。为此,你想要

current_user.mailbox.conversations.last

所以我的疯狂猜测是你可能想要

@conversation = current_user.mailbox.conversations.last

您的代码中的另一个不一致之处是Mailboxer::Conversation生成器创建的基本模型没有questions关系,但是当您说时您似乎假设有一个

@conversation.questions

要将对话与问题联系起来,您必须使用以下内容进行修补:

class Mailboxer::Conversation < ActiveRecord::Base
  has_many :questions
end

在您自己的文件app/models/conversation.rb中。belongs_to :conversation此外,仅当模型中有一个和外键conversation_id时,这才有意义Question。你也没有。

总之,有两个观察结果:

  1. 您需要花一些时间mailboxer通过研究其源代码来了解其工作原理,因为文档很少。

  2. 上述模型中至少存在致命的不一致。其他人很可能。在你有任何成功的希望之前,你必须解决这些问题。这样做的方法是在继续使用控制器之前测试模型。Rails 的成功在于让模型完全正确。

于 2014-06-02T21:49:11.423 回答
0

从邮箱文档中,我可以看到任何邮件都有一个conversation_id. 你声称问题conversation_id没有设置,所以我认为你的问题模型也有一个对话链接?

belongs_to但是我在您的问题模型中没有看到这一点?

所以我看到了一些选择:

  • 要么您应该通过消息访问对话,例如question.message.conversation
  • 要么您希望conversation_id问题的问题与消息的问题相同,请执行以下操作

    @message = current_user.messages.new(...) @question.message = @message @question.conversation_id = @message.conversation_id

您确实保存@question但不保存@message?那是问题吗?

  • 要么你@message不是通过对话创建的,但也许你应该send这样做,就像你在你的MessagesController

    @message = current_user.send_message(.... @question.update_attributes :message_id => @message.id

希望这可以帮助。

于 2014-06-02T22:14:48.617 回答