Preferred way to private messages modeling in Rails 3
A much simpler model is to capture each Message:
class Message < ActiveRecord::Base
belongs_to :from_user, :class_name => 'User' # from_user_id field fk Users
belongs_to :to_user, :class_name => 'User' # to_user_id field fk Users
belongs_to :thread, :class_name => 'Message' # Reference to parent message
has_many :replies, :class_name => 'Message', :foreign_key => 'thread_id'
named_scope :in_reply_to, lambda { |message| :conditions => {:thread => message}, :order => 'created_at' }
end
class User < ActiveRecord::Base
has_many :messages_received, :class_name => 'Message', :foreign_key=> 'to_user_id'
has_many :messages_sent, :class_name => 'Message', :foreign_key=> 'from_user_id'
end
If you need to capture the message threads, any Message that's a reply can store a reference to the initial message starting the Conversation (aka Thread). For example:
first_msg = Message.new(:to_user => bob, :from_user => sally, :body => 'Hello!')
sally_reply = first_msg.replies.build(:to_user => bob, :from_user => sally, :body => 'hi back')
bob_reply = first_msg.replies.build(:to_user => sally, :from_user => bob, :body => 'later')
Rails 3: Setting up private messaging in my rails app?
You can specify the :foreign_key
on both sides, like this:
class User < ActiveRecord::Base
has_many :sent_messages, :class_name => 'Message', :foreign_key => 'from_id'
has_many :received_messages, :class_name => 'Message', :foreign_key => 'to_id'
end
I know Rails 3 has an :inverse_of
option you can pass as well, but I don't have any experience with that.
Modeling Messages between Users
Just as in the Message model:
class User < ActiveRecord::Base
has_many :sent_messages, :class_name => "Message", :foreign_key => "sender_id"
has_many :received_messages, :class_name => "Message", :foreign_key => "receiver_id"
end
MongoDB Conversation / Private Message Schema using Mongoid
I gather that you are using MongoId 3.0. I do not see any problem in your first solution:
messages_in = some_user.messages_received.where(:message_sender => current_user)
messages_out = some_user.messages_sent.where(:message_recipient => current_user).
You can find various examples:
Preferred way to private messages modeling in Rails 3
http://pastebin.com/fKavivbp
https://groups.google.com/forum/?fromgroups=#!topic/mongoid/BOBqhYLb7O0
I have an internal messaging system on several projects with MongoId and use the first solution.
If you add other class "Conversation"
You should not embed message, because a conversation can have an unlimited number of messages. you should use has_may messages
and belongs_to conversation
.
I think that both solutions are good, So you choose your needs for your project logic. If your logic is simpler, you can opt for the first solution. Otherwise, if your logic is more complex opts for the latter solution.
Regards!
Rails private messages how to create a conversation view?
Short answer is: you can't with that gem. You'll have to extend it and add a Conversation model then bridge that between users and messages.
I propose, instead, you use this gem:
https://github.com/ging/mailboxer
Far more powerful than your current gem, and it comes with conversations out of the box. I've used it before to mimic a gmail-like view.
From the guide:
#alfa wants to retrieve all his conversations
alfa.mailbox.conversations
#A wants to retrieve his inbox
alfa.mailbox.inbox
#A wants to retrieve his sent conversations
alfa.mailbox.sentbox
#alfa wants to retrieve his trashed conversations
alfa.mailbox.trash
Easy as pie:
current_user.mailbox.conversations.each do |convo|
convo.subject
...
end
In a migration: how to loop through Models and execute a private method in Model
Just use the Object method send
(it doesn't check protected/private).
Post.all.each do |post|
post.send :create_short_url
post.save!
end
An alternative would be (but that could interfere with other migrations running in the same Ruby-process after that):
Post.before_save :create_short_url
Post.all.each(&:save!)
Visibility tip: Most of the time what you really mean is protected
(see here). I recommend to use protected
instead of private
in this case.
What's the best way to write a (x AND y)OR(a AND b) where query in Rails?
You can clean it up a little by using a SQL string and the array syntax for value interpolation:
class Conversation < ActiveRecord::Base
def initialize(me, them)
@me = me
@them = them
end
def messages
Message.where(["(sender_id = ? AND recipient_id = ?) OR (sender_id = ? AND recipient_id = ?)", @me.id, @them.id, @them.id, @me.id])
end
end
Related Topics
What Is the Use of "#!/Usr/Local/Bin/Ruby -W" at the Start of a Ruby Program
How to Change the Position of an Array Element
Monkey-Patching VS. S.O.L.I.D. Principles
Phusion Passenger Error: You Have Activated Rack 1.2.1, But Your Gemfile Requires Rack 1.2.2
Rails-Like Database Migrations
How to Convert an Array of Strings into a Comma-Separated String
What Is the Meaning of "H" in "<%=H [ ...] %>"
Check If a Hash's Keys Include All of a Set of Keys
Force Bundle Install to Use Https:// Instead of Git:// for Github-Based Gems
How to Get Constants Defined by Ruby's Module Class via Reflection
Ruby Loading Config (Yaml) File in Same Dir as Source
How to Read a Password from the Command Line in Ruby
When to Call a "Require" in Rails
Rails Fields_For Form Not Showing Up, Nested Form