0

我有一个用户到用户的消息传递系统。我试图将一组用户ID传递给ConversationUser(连接表)模型,然后从每个user.id创建多个conversation_usersConversationUser中的两个字段分别为conversation_iduser_id。我可以初始化一个对话用户,因为新的conversation_id被传递给模型,但由于某种原因,用户id的散列没有进入我的模型。我得到一个Validation failed: User can't be blankRails:将参数哈希值传递给模型

我谈话/新视图用于捕捉user_ids:

<%= check_box_tag "conversation_user[recipient][]", user.id %> <%= user.name %><br /> 

我知道这是工作,因为我的PARAMS是我收到回的部分是:

"conversation_user"=>{"recipient"=>["9", "10"]} 

我的Rails的要点4控制器&强PARAMS:

class ConversationsController < ApplicationController 
    def new 
    @user = User.find(params[:user_id]) 
    @conversation = @user.conversation_users.build 
    @conversation.build_conversation.messages.build 
    end 

    def create 
    @conv = Conversation.create! 
    @conversation = @conv.conversation_users.create!(conversation_user_params) 
    end 

    def conversation_user_params 
    params.require(:conversation_user).permit(recipient: []) 
    end 

我ConversationUser模型的要点:

class ConversationUser < ActiveRecord::Base 
    attr_accessor :recipient 

    before_create :acquire_conversation 

    validates :user_id, :conversation_id, presence: true 

    def acquire_conversation 
    unless recipient.blank? 
     recipient.each do |u| 
     ConversationUser.create(user_id: u, conversation: conversation) 
     end 
    end 
    end 
end 

我认为这个问题是在什么地方我控制器conversation_user_params。但它也可能在模型的before_create方法中。我一直试图解决这个问题一天,大量的调试没有成功。如果任何人能够提供帮助,我提前感谢你。

回答

5

问题出在模型中。在创建ConversationUser之前调用before_create回调。让我们将这个创建的ConversationUser命名为CURRENT。因此,在创建CURRENTConversationUser之前,您将循环使用收件人ID并为其中的每一个创建一个ConversationUser。您在此创建的ConversationUser不是CURRENTConversationUserCURRENTConversationUser在回调执行后保存(在创建其他ConversationUser之后)。但是,在这种情况下CURRENTConversationUser不知道至极User它属于,因为你通过你在before_create回调创建user_id参数ConversationUser S,但你在创建时不要将它传递给CURRENTConversationUser(原时候的方法create!是执行)。

要解决此问题,您可以覆盖原始的create!方法,或者完全不用它来创建接收方ID的ConversationUser。添加一个新的方法,以您的Conversation型号(例如create_conversation_users):

解决方案

在控制器:

def create 
    @conv = Conversation.create! 
    @conversation = @conv.create_conversation_users!(conversation_user_params[:recipient]) 
end 

在模型:

class Conversation 
    def create_conversation_users!(recipient_ids) 
    return if recipient_ids.blank? 

    recipient_ids.each do |recipient_id| 
     conversation_users.create!(user_id: recipient_id, conversation: self) 
    end 
    end 
end 

你也应该更新ConversationUser型号:

class ConversationUser < ActiveRecord::Base 
    validates :user_id, :conversation_id, presence: true 
end 
+0

我看到我的错误。非常感谢你。这工作很好。 – user3181113

1

错误发生在ConversationUserbefore_create回调在数据库中创建记录之前运行但运行验证之后运行。为了解决你的问题,你可以做一些事情。其中一个由Chumakoff回答。这是另一个可以使用的选项。

ConversationUser删除的所有代码和更改conversation_user_params

def conversation_user_params 
    params[:conversation_user][recipient].map do |recipient| 
    { user_id: recipient } 
    end 
end 

会发生什么事是你传递的{ user_id: 1 }create!数组这与调用多个create!({ user_id: 1 })

+0

呵呵。有趣。从未想过在参数中使用do块。谢谢。 – user3181113