Rails:将params hash传递给模型

use*_*113 0 ruby activerecord ruby-on-rails actioncontroller strong-parameters

我有一个用户到用户的消息系统.我正在尝试将一组用户ID传递给ConversationUser(连接表)模型,然后conversation_users从每个人创建多个user.id.这两个领域ConversationUserconversation_iduser_id.我能够初始化单个会话用户,因为新conversation_id的传递给模型,但由于某种原因,用户ID的哈希不会到达我的模型.我得到了一个Validation failed: User can't be blank

我的对话/捕获user_ids的新视图:

<%= check_box_tag "conversation_user[recipient][]", user.id %> <%= user.name %><br />
Run Code Online (Sandbox Code Playgroud)

我知道这是有效的,因为我收到的部分短信是:

"conversation_user"=>{"recipient"=>["9", "10"]}
Run Code Online (Sandbox Code Playgroud)

我的Rails 4控制器的基本要点和强大的参数:

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
Run Code Online (Sandbox Code Playgroud)

我的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
Run Code Online (Sandbox Code Playgroud)

我认为问题出在我控制器的某个地方conversation_user_params.但它也可能在模型的before_create方法中.我一直试图解决这个问题一天,有很多调试没有成功.如果有人可以提供帮助,我会提前感谢你.

chu*_*off 5

问题出在模型中.before_create在创建之前调用回调ConversationUser.让我们把它命名ConversationUserCURRENT.因此,在创建之前,CURRENT ConversationUser通过收件人ID循环并ConversationUser为每个人创建一个.在ConversationUser您创建下面就都没有CURRENT ConversationUser.CURRENT ConversationUser执行回调后保存(在创建其他ConversationUsers之后).但是在这种情况下 CURRENT ConversationUser不知道User它属于哪个,因为你将user_id参数传递给ConversationUser你在before_create回调中创建的s ,但是在创建它CURRENT ConversationUser时不会将它传递给它(当create!执行原始方法时).

要解决此问题,您可以覆盖原始create!方法或根本不使用它来ConversationUser通过收件人ID 创建s.向Conversation模型添加新方法(例如create_conversation_users):

在控制器中:

def create
  @conv = Conversation.create!
  @conversation = @conv.create_conversation_users!(conversation_user_params[:recipient])
end
Run Code Online (Sandbox Code Playgroud)

在模型中:

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
Run Code Online (Sandbox Code Playgroud)

你还应该更新ConversationUser模型:

class ConversationUser < ActiveRecord::Base
  validates :user_id, :conversation_id, presence: true 
end
Run Code Online (Sandbox Code Playgroud)