Rails:将params hash传递给模型

时间:2014-03-13 06:36:42

标签: ruby-on-rails ruby activerecord strong-parameters actioncontroller

我有一个用户到用户的消息系统。我尝试将一组用户ID传递给ConversationUser(联接表)模型,然后从每个conversation_users创建多个user.idConversationUser中的两个字段为conversation_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 />

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

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

我的Rails 4控制器的基本功能&amp;强烈的参数:

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方法中。我一直试图解决这个问题一天,经过大量调试但没有成功。如果有人可以提供帮助,我会提前感谢你。

2 个答案:

答案 0 :(得分:5)

问题出在模型中。在创建before_create之前调用ConversationUser回调。我们将此名称ConversationUser命名为CURRENT。因此,在创建CURRENT ConversationUser之前,您循环访问收件人ID并为每个人创建ConversationUser。您在此处创建的ConversationUser不是CURRENT ConversationUser。执行回调后(在创建其他CURRENT之后)保存ConversationUser ConversationUser。但在这种情况下,CURRENT ConversationUser并不知道它属于User,因为您将user_id参数传递给您创建的ConversationUserbefore_create回调,但在创建CURRENT ConversationUser时(执行原始create!方法时)不会将其传递给create! {。}}。

要解决此问题,您可以覆盖原始ConversationUser方法,或者根本不使用它来通过收件人ID创建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 型号:

{{1}}

答案 1 :(得分:1)

错误发生在ConversationUser。运行验证后,在数据库 BUT 中创建记录之前,将运行before_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 })相同。