Rails关联构建具有强大的参数和参数

时间:2015-11-19 00:01:46

标签: ruby-on-rails

在我的消息控制器中,我希望构建一条属于@sender(类字符)的消息。但是,消息不仅属于字符而且属于对话,这导致了问题。消息的构建方法需要传递它所属的Conversation id,以便消息可以传递验证。我的代码通过sql搜索成功找到@conversation,但是如何正确地将@ conversation.id和message_params作为强参数传递给@ sender.messages.build?

messages_controller.rb

def create
  @sender    = Character.find_by(callsign: params[:callsign])
  @recipient = Character.find_by(callsign: params[:recipient])
  sender_id    = @sender.id
  recipient_id = @recipient.id
  conversationID = Conversation.find_by_sql("
            SELECT senderConversations.conversation_id FROM Chats AS senderConversations
            INNER JOIN Chats AS recipientConversations
                ON senderConversations.conversation_id=recipientConversations.conversation_id
            WHERE senderConversations.character_id='#{sender_id}'
                AND recipientConversations.character_id='#{recipient_id}'
            GROUP BY senderConversations.conversation_id
            HAVING count(distinct senderConversations.character_id) = 2
  ; ")
  @conversation = Conversation.find_by(id: conversationID)
  if(@conversation.nil?)
    @conversation = @sender.conversations.create
    @recipient.conversations << @conversation
  end # It all works great up to here!
  @message = @sender.messages.build(message_params, @conversation) # Can't get this working
  if @message.save
    @conversation.messages << @message
    respond_to do |format|
      format.html do
      end
      format.js do
      end
    end
  else
    redirect_to request.referrer || root_url
  end
end

private

  def message_params
    params.require(:message).permit( :content, :picture )
  end

character.rb

has_many :chats,  foreign_key: "character_id",
                  dependent: :destroy
has_many :conversations, through: :chats, source: :conversation
has_many :messages

conversation.rb

has_many :messages

chat.rb

belongs_to :character
belongs_to :conversation

message.rb

belongs_to :character
belongs_to :conversation
validates :character_id, presence: true
validates :conversation_id, presence: true

1 个答案:

答案 0 :(得分:1)

要在邮件中添加对话,请尝试

@message = @sender.messages.build(message_params.merge(:conversation => @conversation))

一些建议 -

首先,将所有查询代码移至Message模型。鉴于您设置的参数,发件人和收件人,您应该能够找到或创建对话并正确附加。降低控制器的复杂性。

此外,如果可以并且设置范围,请尝试将该sql移动到rails查询中。不确定我是否完全理解架构,但有点类似......

class Conversation < ActiveRecord::Base

  scope :between, (sender, recipient) -> { joins(:chats).where(:charcter_id => [sender, recipient]).group('chats.conversations_id').having("count(distinct senderConversations.character_id) = 2") }

然后,您可以在before_save或before_validation回调中查找对话,确保对话存在。在范围内,您可以更轻松地重用sql以在其他情况下查找对话。