Best route for adding conversations to messages - ruby-on-rails

I have a inbox system but I am not sure how to implement a reply to feature. All messages should belong to some other entity, e.g. a "conversation". When the first message is created, the conversation is also created. All subsequent messages are then part of that conversation. Conversations can only occur between two users, there are no options to allow people to forward messages, or add more people to the conversation. If the users exchange several messages back and forth using the 'reply' action..the users should be able to view their past messages from that conversation in the view. What would be the requirements for doing this? Should I create a conversation model or can I add a new column to the Messages table conversation_id. If a user replies to message id 27, then it would create a new message id 28 and the conversation_id value would be 27. Then I can just do a desc from conversation_id 27. That will show the history of all messages that belong to id 27.

You want to populate a recipient_id on the new Message in your new action? Is that right?
If a conversation is guaranteed to only have two users, you could do something like
current_conversation.users.select { |u| u.id != current_user.id }
or
User.joins(:conversations).where("conversations.id = ? AND users.id != ?", current_conversation.id, current_user.id).first
You're using the phrase "reply to", so I'm assuming the conversation already exists. If it doesn't, the author has to specify the other user in the conversation anyway.

You may want to take a look at the Mailboxer Gem's sourcecode, you might find some of your answers in there.

Related

I wish to display a "show" action for two different models at the same; how do I go about this?

So I am making a little chat application to practice Ruby and Rails, and the way I want the actual chat view to work is basically like Discord, if you're familiar with that: a list of chats you are a part of on the left in a scrollable list, and on the right is the messages from the chat that you have selected, so you can click on the name of a chat on the left, and the messages appear on the right.
I have set it up so that chats and messages are separate models; the chat model just has an ID, a name and a list of participants, while a Message has its own ID, the ID (basically) of the chat it belongs to, the sender's ID, the content, and the date/time it was sent.
My question is: how can I display an index of two different models at the same time? Like, as far as I have used Rails so far, there would be one route/action for showing the list of channels, and one for showing the messages for a given channel, each corresponding to a different method on a different Controller. But I want to display both actions using one route, essentially (say the route would be /chat).
Put it in the Index Method in your Controller.
def Index
#chats = Chat.all #you'll normally have this Kind already in your method
#messages = Message.all
end
Is that what you mean?

mailboxer gem - find message sender

I am having the hardest time with the mailboxes gem. I have gotten it working in that I can send and receive messages, but for the life of me I cannot figure out how to display them. i want to display the inbox in table organized like this:
message sender | message subject | message sent date
I have been working for hours to try and figure out how to access the sender of the message in the receivers inbox, but I can't figure it out. I've tried looping through conversations, receipts, notifications, etc and I still cannot figure out what to do. I can't use:
#user wants to retrieve all his conversations
user.mailbox.conversations
#user wants to retrieve his inbox
user.mailbox.inbox
#user wants to retrieve his sent conversations
user.mailbox.sentbox
because there is no way to organize how the messages are displayed using those methods (at least as far as I know). How can I loop through the messages and find the message sender for each message?
A Mailboxer::Message is a Mailboxer::Notification
And you can have the notification's sender: message.sender
A Mailboxer::Conversation is a collection of messages.
You can get the participants, even the originator (plus many other) from it.
Is it clearer?

Issue and clarification needed with attr_accessible

There is so much written about the security threat of attr_accessible that I am beginning to wonder if I should even have any attributes in it. Here is the issue. I have a Message model which has the following:
attr_accessible :body,:sender_id,:recipient_id
I do not have the update or edit action in my messages_controller. With the new and create action I am able to create a new message and send it to a recipient. Only users who have logged in and meet certain conditions can message each other. I do that with the help of a before_filter and the conditions work fine. The message is stored and can be viewed by the sender and the recipient. Perfect!
The question I have is that since :body,:sender_id,:recipient_id are included in attr_accessible, can a malicious user somehow change the :body,:sender_id,:recipient_id of the original message? Should I just add these attributes to attr_readonly as well so they cannot be modified once saved?
This question has been haunting me for practically all my models.
can a malicious user somehow change the :body,:sender_id,:recipient_id
of the original message?
This would depend on other things rather than attr_accesible. attr_accesible will only filter which fields are allowed to be updated using mass assignment. Since you say you don't have any update action, then no, there is now way a user can edit a message since you always create a new Message through you create action.
But there is something you need to care about. What is sender_id? If you do have users in your app and they send messages to each others, then sender_id should not be an accessible field, since this will allow users to send messages on behalf of other users. You probably want to keep that field off the attr_accessible list and do something like this:
m = Message.new params[:message] # body and recipient_id
m.sender_id = current_user.id # this is not mass assignment
m.save
.....
Well, it depends on how your are creating your model's instance. If you use:
FooModel.create(params[:foo])
then yes, your are not secure because a logged in user may pass additional parameters to the request even if you don't provide explicitly form fields for those attributes.
So, for your case, anyone posting to your "create" action with sender_id, recipient_id (values in the request) will be able to change them unless you take care about this assignments in your action.

Emailng-list based on query beeing updated automaticcaly from that query

i have emailing-list(based on some params) being automatically updated from an existing query. I explain : I have an emailing list (containing only email addresses) called "new users list" that will automaticcaly be updated whenever there are new users. I assume this is going to be done by a query stocked somewhere!
Any ideas?
Add a postInsert() listener in your User model to automatically insert the new user's email to the email addresses whenever a new user is added.
Actually what is your question. is it how emailing list is being updated?.
if your question is how that emailing list is being updated than it can be a trigger on the table where new users being register.

Rails efficient way to save non-duplicates?

I have a type I want to save to the database, say, email addresses, and I want to save them in the most efficient way possible. I also want to associate posts with email addresses, so if it exists, I want to assign the post to that email address. Should I do a search first and then go based on that result, or is there a more efficient way? for ex, if it doesn't exist, I just want it to insert, I don't want to then to have to insert it after a search; that takes 2 calls where 1 would do.
I believe you should use something like find_or_create.
Does post and email are separated models and post has_one email?
Edit
When creating a post, you should do something like
# posts controller
#email = Email.find_or_initialize_by_address(params[:email])
#post.email = #email #or whatever you do to associate them

Resources