I have a User class with reference to a Message class. The message class has a user_id (which is the sender) and a receiver_id. So in the User class I have
has_many :messages
has_many :messages, :foreign_key => "receiver_id"
and then in the Message class I have
belongs_to :user
The first relationship -- via user_id -- goes perfectly well. I haven't the slightest idea what to put in the Message class for the second relationship. The messages table is built with both user_id and receiver_id, so the support is there.
Is this even possible?
Also, then I'd have no idea how to get to the messages RECEIVED by a user... or the User who received a message :)
[I know that I can work around this by having a sender table and a receiver table and a messages table and maybe a bunch of other tables (a conversations table!), but I'd like to do it like this, for the fun of it. This application will be used for learning only.]
Also important: where would the docs be for this? This is not very helpful.
In your User class:
has_many :messages
has_many :received_messages,
:foreign_key => "receiver_id", :class_name => "Message"
In your Message class:
belongs_to :user
belongs_to :receiver, :class_name => "User"
#user = User.first
#user.messages
#user.received_messages
Related
Im new to Rails and actually im trying to write my own messaging application. So far i have many users with username, password, etc. And now im figuering out how i should best write the migration for the message model. I thought that a message needs:
Message
sender_id => integer
recipent_id => integer
created_at => time
updated_at => time
The first problem im facing is that of course sender_id is unique but what is with recipent_id, there are often messages that should go to several people!
Next problem is i dont know how i have to refer form the user model to the message model i mean normaly i would write:
User has_many :messages
Message belongs_to :user
To do this i would need a coulmn named user_id in the message model , but now i have two cloumns sender_id and reciepent_id!
I hope you can give my some hints! Thanks
Is this what you are looking for?
class User < ActiveRecord::Base
has_many :messages, :foreign_key => "sender_id" #this only gives the messages sent by the user.
end
class Message < ActiveRecord::Base
#sender_id
belongs_to :sender, :class => "User", :foreign_key => "sender_id"
has_many :recipients, :class => "MessageRecipient"
end
class MessageRecipient < ActiveRecord::Base
belongs_to :message
belongs_to :recipient, :class => "User", :foreign_key => "recipient_id"
end
If you want to get all the recipients for the message, you could do
message.recipients.collect(&:email)
I have a message model (Message) and this models as a userTo and userFrom, so two references to User. How can i write the migration? My user model is User.
Thank you
Here's a complete answer to this issue, in case people visiting this question are having a hard time putting everything together (as I was when I first looked into this).
Some parts of the answer take place in your Migrations and some in your Models:
Migrations
class CreateMessages < ActiveRecord::Migration
create_table :messages do |t|
def up
t.references :sender
t.references :recipient
end
end
end
Here you are specifying that there are two columns in this table that will be referred to as :sender and :recipient and which hold references to another table. Rails will actually create columns called 'sender_id' and 'recipient_id' for you. In our case they will each reference rows in the Users table, but we specify that in the models, not in the migrations.
Models
class Message < ActiveRecord::Base
belongs_to :sender, :class_name => 'User'
belongs_to :recipient, :class_name => 'User'
end
Here you are creating a property on the Message model named :sender, then specifying that this property will be referencing an instance of the User class. Rails, seeing the "belongs_to", will look for a column in your database called "sender_id", which we defined above, and use that to store the foreign key. Then you're doing the exact same thing for the recipient.
This will allow you to access your Sender and Recipient, both instances of the User model, through an instance of the Message model, like this:
#message.sender.name
#message.recipient.email
Here is your User 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 => 'recipient_id'
end
Here you are creating a property on the User Model named :sent_messages, specifying that this property is related to the Message Model, and that the foreign key on the Message model which relates to this property is called 'sender_id'. Then you are doing the same thing for received messages.
This allows you to get all of a users sent or received messages by doing something like this:
#user.sent_messages
#user.received_messages
Doing either of these will return an array of instances of the Message model.
In the migration, create two different columns for each kind of user. For example:
add_column :messages, :sender_id, :integer
add_column :messages, :receiver_id, :integer
Then in the model, that's where the logic to map each column to the User class happens:
belongs_to :sender, :class_name => 'User'
belongs_to :receiver, :class_name => 'User'
Of course, use your own words for sender and receiver, but Rails will automatically associate sender to the sender_id column (and the same logic for receiver)
You will then be able to interact with both user user.sender and user.receiver.
I am wondering whether there is a way to do this with rails or not. Basically I have a user model and an event model. Event is created by a user and I want to have a foreign key (user_id) in the event model that indicates who created the event. Additionally, event can have many users who attend it so the event model becomes something like
belongs_to :user
has_many :users, :through => :guests #suppose i have the guest model
and the user model looks something like
has_many :events, :through => :guests
I have not tried this association yet but I want to be able to say
e = Event.find(1)
e.creator #returns the user who created this event
instead of
e.user
is there a way for me to do this?
Simply pass some options to belongs_to:
belongs_to :creator, :class_name => "User", :foreign_key => "user_id"
This specifies that the creator method will be a User object, referencing the user_id field.
I have the following scenario that I want to model the best way for a Rails application.
I have a contact model that belongs to a company. A contact can create an enquiry so contact can have many enquiries. The enquiry can have many messages that can be from and to many contacts. Messages can belong to an enquiry, a company or a contact.
This has been confusing me on how best to model this. Any ideas?
Best regards,
Richard Moss
It seems that Message should be polymorphic in this case, since they can belong to many different models. Because contacts can send messages to other contacts, Contact will have two associations with messages, one for sent_messages and the other for received_messages. Message will be tied to a sender through contact_id.
class Contact < ActiveRecord::Base
belongs_to :company
has_many :enquiries
has_many :sent_messages, :class_name => "Message"
has_many :received_messages, :as => :messageable, :class_name => "Message"
end
class Company < ActiveRecord::Base
has_many :contacts
has_many :messages, :as => :messageable
end
class Enquiry < ActiveRecord::Base
belongs_to :contact
has_many :messages, :as => :messageable
end
class Message < ActiveRecord::Base
belongs_to :contact
belongs_to :messageable, :polymorphic => true
end
This should model your relationship requirements pretty well. If you want to better understand it, the Railscast on Polymorphic Associations might be of some insight as well.
It sounds like the confusion is on the messages, rather than the other parts.
I'd go with belongs_to for each of enquiry, company and contact (I'm assuming that you have some messages not associated with enquiries). Then I'd do a custom validation to make sure that at least one of those was specified - but otherwise don't do a validates_presence_of for any of them.
A helper method could ease the pain of finding what a given message is associated with, so you don't have to check each of those three relations looking for one that is not nil.
I want to implement a messaging system for my app.
I have users.
What exactly should I do?
create a messages model with foreign two user foreign keys??.. what would be the most approproate way of getting this done?
My worry is that if I query "message.user" I wont know if Id be getting the sender of the receiver of the message
Use two separate foreign keys with approprately named belongs_to relations to distinguish between senders and receivers.
Given a message model with the foreign keys sender_id and receiver_id you can do:
class Message < ActiveRecord::Base
belongs_to :sender, :class_name => "User", :foreign_key => "sender_id"
belongs_to :receiver, :class_name => "User", :foreign_key => "receiver_id"
end
Now you'll be able to reference a message's sender using message.sender and receiver using message.receiver.