Reputation: 2157
However, I'm getting the behavior of user avatars
rendering on the wrong side due to a Rails partial
.
# conversations/_message.html.erb
<% if current_user.id == message.user_id %>
<Display Avatar Right>
</Display Avatar Right>
<% else %>
<Display Avatar Left>
</Display Avatar Left>
<% end %>
When a message belongs to the current user, the avatar needs to be on the right, when not, the avatar needs to be on the left.
In the create_message
method of my MessagesChannel
, this is the method that is called when a user creates a new message. The issue is, when a message is created, current_user
is the user who created the message. This will render the correct HTML for This user ALONE. Other users/subscribers to the channel will be broadcasted the SAME HTML... this will result in the bug seen in the first screen shot.
def create_message(message_params)
message = Message.new context_type: 'Conversation'
message[:body] = message_params['data']['body']
message[:context_id] = message_params['data']['conversation_id']
message[:user_id] = message_params['data']['user_id']
data = {}
if message.save
data[:html] = ApplicationController.render partial: 'conversations/message', locals: { message: message, current_user: current_user }
else
p message.errors.full_messages.to_sentence
data[:html] = "Error: #{message.errors.full_messages.to_sentence}"
end
ActionCable.server.broadcast('room', data)
end
# conversations/_message.html.erb
if current_user.id == message.user_id
will always return true and the avatar displays on the right even for other users(users who are subscribed to this channel.)
Another thing is, I don't want to touch the behavior in the partial because for the user who sent the message, the html sent back from the MessagesChannel
is correct(it renders the avatar on the right.)
Anyone know a workaround where I can still use this _message
partial? Thanks!
Upvotes: 0
Views: 900
Reputation: 11
hej, your partial is being rendered before being broadcasted. the broadcast_to method transmits a string which is the rendered html of the partial. as a result, when you render your partial, the current_user is the one who sends the message and therefore it is rendered the way the sender sees the partial. a solution could be to pass a boolean variable "sender" to your partial, i.e.
<% if sender %>
<Display Avatar Right>
</Display Avatar Right>
<% else %>
<Display Avatar Left>
</Display Avatar Left>
<% end %>
then you transmit both the sender and the receiver partials in the data object and the sender Id, e.g.
data[:htmlSender] = ApplicationController.render partial: 'conversations/message', locals: { message: message, sender: true }
data[:htmlReceiver] = ApplicationController.render partial: 'conversations/message', locals: { message: message, sender: false, } data[:senderId] = current_user.id.to_s
then you make a conditional in the received(data) callback where you compare the senderId from your data Object with the current_user id and insert either data.htmlSender or data.htmlReceiver.
Upvotes: 1
Reputation: 899
current_user.id = message.user_id
this is an assignment. The control flow will always go into if block. Using ==
should be right.
Upvotes: 0
Reputation: 4920
You have typed <% if current_user.id = message.user_id %>
.
Replace =
with ==
.
=
will return the value of message.user_id
which is truth in your case.
Upvotes: 0