在我的消息控制器中,我希望构建一条属于@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
答案 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以在其他情况下查找对话。