I currently have two models. These are user and message. Message belongs to user and user has many messages. I have set the relation up so I can do something like the following... #code current_user.messages ##end code This gets a list of all of the incoming messages for the logged user. This works just fine. What I really want to do, is to be able to say something like... #code message.sender ##end code and have this return a model of the user that sent the message. What''s the best way to achieve this if I already have one relation? I have a field in the user model that is set up to record the user ID of the person who sends the message. I am just not sure how to express the relationship in rails using active record. Any help would be greatly appreciated. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk -~----------~----~----~----~------~----~------~--~---
Well i thought about this issue too sometime ... and though i''m perfectly sure, this could work: class Message < ActiveRecord::Base belongs_to :sender, :foreign_key => "sender_id", :class => "User" belongs_to :recipient, :foreign_key => "recipient_id", :class => "User" end class User < ActiveRecord::Base has_many :sentmessages, :foreign_key => "sender_id", :class => "Message" has_many :rcvdmessages, :foreign_key => "recipient_id", :class => "Message" end Then you *should* be able to do: somevariable = message.sender somevariable = message.recipient sentmsgs = user.sentmessages.find :all rcvdmsgs = user.rcvdmessages.find :all So you practically reference the other class twice in both Models, but with different assiciation names (:sender <-> :recipient and :sentmessages <-> :rcvdmessages) and foreig keys ( sender_id <-> recipient_id). That creates two different associations with the same Model .... Someone please correct me if i''m wrong, i never tested it and only made my own thoughts from the rails docs As i want to use soemthing like this myself soon, and IF the above is correct, i want to ask: How is the best way to store the messages twice, so sender + recipient can both keep a copy and delete it whenever they want? Anyone got any idea? --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk -~----------~----~----~----~------~----~------~--~---
On 10/18/06, Stewart <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > > I currently have two models. These are user and message. > > Message belongs to user and user has many messages. I have set the > relation up so I can do something like the following... > > #code > current_user.messages > ##end code > > This gets a list of all of the incoming messages for the logged user. > This works just fine. > > What I really want to do, is to be able to say something like... > > #code > message.sender > ##end code > > and have this return a model of the user that sent the message. What''s > the best way to achieve this if I already have one relation? I have a > field in the user model that is set up to record the user ID of the > person who sends the message. I am just not sure how to express the > relationship in rails using active record.You can use the dynamic finder: message.find_sender_by_id( :id => userID ) This is the simplest way to find the sender object. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk -~----------~----~----~----~------~----~------~--~---
Thorsten L wrote:> Well i thought about this issue too sometime ... and though i''m > perfectly sure, this could work: > > class Message < ActiveRecord::Base > belongs_to :sender, :foreign_key => "sender_id", :class => "User" > belongs_to :recipient, :foreign_key => "recipient_id", :class => > "User" > end > > > class User < ActiveRecord::Base > has_many :sentmessages, :foreign_key => "sender_id", :class => > "Message" > has_many :rcvdmessages, :foreign_key => "recipient_id", :class => > "Message" > end > > Then you *should* be able to do: > > somevariable = message.sender > somevariable = message.recipient > > sentmsgs = user.sentmessages.find :all > rcvdmsgs = user.rcvdmessages.find :all > > So you practically reference the other class twice in both Models, but > with different assiciation names (:sender <-> :recipient and > :sentmessages <-> :rcvdmessages) and foreig keys ( sender_id <-> > recipient_id). > That creates two different associations with the same Model .... > Someone please correct me if i''m wrong, i never tested it and only made > my own thoughts from the rails docs > > As i want to use soemthing like this myself soon, and IF the above is > correct, i want to ask: > > How is the best way to store the messages twice, so sender + recipient > can both keep a copy and delete it whenever they want? > Anyone got any idea?i like your suggestion. Bala what your suggesting is easy and thats what i was going to go with but that would require more code than i would like in the view.... I worked it out with the help of the api class Message < ActiveRecord::Base belongs_to :user validates_presence_of :title, :body belongs_to :sender, :class_name => "User", :foreign_key => "user_id" end thats all i had to do. For the record the hash is :class_name not :class Also... the first hash you pass the belongs_to method must match the key in the current model your dealing with. So problem solved thanks for that... I looked in to it a bit more and i am finding you can do a lot with the model... such as this, has_many :users, :order => "last_name" now when ever i list the users its always in alpha... how easy is that! -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk -~----------~----~----~----~------~----~------~--~---
Stewart wrote:> Thorsten L wrote: >> Well i thought about this issue too sometime ... and though i''m >> perfectly sure, this could work: >> >> class Message < ActiveRecord::Base >> belongs_to :sender, :foreign_key => "sender_id", :class => "User" >> belongs_to :recipient, :foreign_key => "recipient_id", :class => >> "User" >> end >> >> >> class User < ActiveRecord::Base >> has_many :sentmessages, :foreign_key => "sender_id", :class => >> "Message" >> has_many :rcvdmessages, :foreign_key => "recipient_id", :class => >> "Message" >> end >> >> Then you *should* be able to do: >> >> somevariable = message.sender >> somevariable = message.recipient >> >> sentmsgs = user.sentmessages.find :all >> rcvdmsgs = user.rcvdmessages.find :all >> >> So you practically reference the other class twice in both Models, but >> with different assiciation names (:sender <-> :recipient and >> :sentmessages <-> :rcvdmessages) and foreig keys ( sender_id <-> >> recipient_id). >> That creates two different associations with the same Model .... >> Someone please correct me if i''m wrong, i never tested it and only made >> my own thoughts from the rails docs >> >> As i want to use soemthing like this myself soon, and IF the above is >> correct, i want to ask: >> >> How is the best way to store the messages twice, so sender + recipient >> can both keep a copy and delete it whenever they want? >> Anyone got any idea? > > i like your suggestion. Bala what your suggesting is easy and thats what > i was going to go with but that would require more code than i would > like in the view.... > > I worked it out with the help of the api > > class Message < ActiveRecord::Base > belongs_to :user > validates_presence_of :title, :body > belongs_to :sender, :class_name => "User", :foreign_key => "user_id" > end > > thats all i had to do. For the record the hash is :class_name not :class > > Also... the first hash you pass the belongs_to method must match the key > in the current model your dealing with. > > So problem solved thanks for that... > > I looked in to it a bit more and i am finding you can do a lot with the > model... such as this, > > has_many :users, :order => "last_name" > > now when ever i list the users its always in alpha... > > how easy is that!It''s possible I am not as smart as they think I am. class Message < ActiveRecord::Base belongs_to :sender, :class_name => "User", :foreign_key => "user_id" end the above line of code works fine for me when I do something like this... <%= message.sender.full_alpha_name %> however, when I am trying to create a new message with the following code... def sendmessage @message = Message.new() @message.body = params[:message][:body] @message.title = params[:message][:title] @message.user_id = params[:message][:to] @message.sender = current_user if @message.save flash[:notice] = "Message Sent" redirect_to :action => "index" else flash[:notice] = "Message not Sent" redirect_to :action => "index" end end both the sender and the userid are set to the wrong values in the database. The sender always has a value of 0 in the database. The userid always has a value of 1. I have checked the form variables and they are fine. When I comment out the following line everything works correctly #belongs_to :sender, :class_name => "User", :foreign_key => "user_id" Am I missing something here? Do I need to do something in my user model apart from has_many :messages thanks in advance for any help. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk -~----------~----~----~----~------~----~------~--~---
Stewart wrote:> It''s possible I am not as smart as they think I am. > > class Message < ActiveRecord::Base > belongs_to :sender, :class_name => "User", :foreign_key => "user_id" > end > > the above line of code works fine for me when I do something like > this... > > <%= message.sender.full_alpha_name %> > > however, when I am trying to create a new message with the following > code... > > def sendmessage > @message = Message.new() > > @message.body = params[:message][:body] > @message.title = params[:message][:title] > @message.user_id = params[:message][:to] > @message.sender = current_user > > if @message.save > flash[:notice] = "Message Sent" > redirect_to :action => "index" > else > flash[:notice] = "Message not Sent" > redirect_to :action => "index" > end > > end > > both the sender and the userid are set to the wrong values in the > database. The sender always has a value of 0 in the database. The > userid always has a value of 1.Hang on. You should only have one column in your ''messages'' table that relates to this join, and that column should be ''user_id''. You shouldn''t have a column that called ''sender''. As far as I can tell, that code should work fine, as long as current_user contains a saved User object. When you say "The sender always has a value of 0 in the database. The userid always has a value of 1.", exactly which tables and columns are you talking about? Chris --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk -~----------~----~----~----~------~----~------~--~---
i think you got something twisted up. -> in the model, you say, the sender''s foreign key is "user_id" -> in the controller, you assign the recipient ( params[:message][:to]) to the column "user_id">From what you described i guess you have a foreign_key "sender" in yourmessage table that shold hold the ID of the user who sent the message, and the "user_id" filed should hold the name of the recipient of the message Your column naming could be more self-explanatory, e.g. use "recipient_id" as i suggested in my above post i think, your :belongs_to sould look like this: belongs_to :sender, :class_name "User", :foreign_key => "sender" belongs_to :recipient, :class_name "User", :foreign_key => "user_id" but you should give some more info, like your exact table layout etc ... and what do the parameters hold? i guess params[:message][:to] hold the recipients name. well you need that user''s id, not his name. But im just guessing here, not enough insight and info.... --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk -~----------~----~----~----~------~----~------~--~---
Thorsten L wrote:> i think you got something twisted up. > -> in the model, you say, the sender''s foreign key is "user_id" > -> in the controller, you assign the recipient ( params[:message][:to]) > to the column "user_id" > >>From what you described i guess you have a foreign_key "sender" in your > message table that shold hold the ID of the user who sent the message, > and the "user_id" filed should hold the name of the recipient of the > message > Your column naming could be more self-explanatory, e.g. use > "recipient_id" as i suggested in my above post > > i think, your :belongs_to sould look like this: > > belongs_to :sender, :class_name "User", :foreign_key => "sender" > belongs_to :recipient, :class_name "User", :foreign_key => "user_id" > > but you should give some more info, like your exact table layout etc > ... > and what do the parameters hold? i guess params[:message][:to] hold the > recipients name. well you need that user''s id, not his name. > > But im just guessing here, not enough insight and info....Ok sorry i should have posted this stuff beofre... here we go class CreateUsers < ActiveRecord::Migration def self.up create_table "users", :force => true do |t| t.column :login, :string t.column :email, :string t.column :crypted_password, :string, :limit => 40 t.column :salt, :string, :limit => 40 t.column :created_at, :datetime t.column :updated_at, :datetime t.column :remember_token, :string t.column :remember_token_expires_at, :datetime t.column :first_name, :string, :null => false t.column :last_name, :string, :null => false t.column :organization_id, :integer, :null => false t.column :title, :string t.column :location, :string end end def self.down drop_table "users" end end class CreateMessages < ActiveRecord::Migration def self.up create_table :messages do |t| t.column :title, :string, :null => false t.column :body, :text, :null => false t.column :user_id, :integer, :null => false t.column :sender, :integer, :null => false t.column :created_at, :datetime, :null => false t.column :read_at, :datetime end end def self.down drop_table :messages end end the sender column in the message table stores the user_id of the user sending the message the user_id in the message table contains the id number of the user that is the recipient (I will later change this to recipient_id its a better name) params[:message][:to] is the id of the user that the message is being set to. The code looks like this... <p><label for="message_to">To</label><br/> <%= collection_select("message", "to" , current_user.organization.users, "id", "full_alpha_name" ) %></p> its all working now though i just needed to fix up my keys and add in that other belongs_to.. Thanks soo much for that guys! -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk -~----------~----~----~----~------~----~------~--~---