2015-07-03 3 views
0

У меня есть сообщение модели, которое имеет атрибуты message:text | date_sent:date. Он также должен иметь from_member и to_member, представляющий пользователя, отправившего сообщение, и пользователя, который его получил.Как сделать два внешних ключа одной и той же модели?

Как это сделать в Rails? Я читал, что соглашение будет member_id для ForeignKey для члена модели. Но, если я хочу, чтобы два поля ссылались на Member?

+1

Вы можете сделать свой has_many/belongs_to ассоциаций с пользовательским именем и указанием внешнего ключа. Что-то вроде has_many: to_member, foreign_key:: to_member_id, class_name: 'Member'. Я сделал это благодаря документу, я проверю, чтобы найти ссылку. –

ответ

2

Я хотел бы сделать что-то вроде этого (отрегулировать опечатку для ваших потребностей и ясности коды):

message.rb 

belongs_to :sender, foreign_key: :sender_id, class_name: 'Member' 
belongs_to :receiver, foreign_key: :receiver_id, class_name: 'Member' 


member.rb 

has_many :message_sent, foreign_key: :sender_id, class_name: 'Message' 
has_many :message_reveived, foreign_key: :receiver_id, class_name: 'Message' 

Затем вы можете сделать, например:

@message.sender and @message.receiver 

@member.message_sent and @member.message_reveived 

Для переноса данных:

def change 
    add_column :messages, :sender_id, :integer 
    add_column :messages, :receiver_id, :integer 
    add_index :messages, :sender_id 
    add_index :messages, :receiver_id 
end 
+0

Как насчет генератора? Как я могу указать поля? – RafaelC

+0

Обычно я добавляю их вручную и при необходимости добавляю индекс. Как t.integer: sender_id, index: true –

+0

Генератор просто добавляет целое число и индекс. Остальное происходит из соглашения rails (именование ...). Это легко воспроизвести вручную. –

2

Вы можете указать тип данного объединения:

class Message < ActiveRecord::Base 
    belongs_to :from_member, class_name: 'Member' 
    belongs_to :to_member, class_name: 'Member' 
end 

и

class Member < ActiveRecord::Base 
    has_many :sent_messages, class_name: 'Message', foreign_key: :from_member_id 
    has_many :received_messages, class_name: 'Message', foreign_key: :to_member_id 
end 

В вашей базе данных,: сообщения нужны атрибуты :from_member_id и :to_member_id

так в вашей миграции его:

def change 
    add_column :messages, :from_member_id, :integer 
    add_column :messages, :to_member_id, :integer 

    add_index :messages, :from_member_id 
    add_index :messages, :to_member_id 
end 
+0

yes или указать foreign_key, который вы используете (иногда разные имена лучше для ясности) –

+0

ну, Rails - это соглашение , поэтому не настраивайте то, что определено в соглашении. И я вижу вашу мысль. Иногда хорошо иметь подсказку, чтобы запомнить конвенцию. –

+0

Да, я полностью согласен. Забавно, что мы можем с почти одинаковым ответом одновременно! Я бы просто добавил индекс в перенос, я предполагаю, что будет много сообщений, будет быстрее получить отправителей/получателей –

Смежные вопросы