Write a migration with reference to a model twice

后端 未结 2 856
情书的邮戳
情书的邮戳 2021-02-04 21:16

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

相关标签:
2条回答
  • 2021-02-04 21:33

    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.

    0 讨论(0)
  • 2021-02-04 21:53

    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.

    0 讨论(0)
提交回复
热议问题