Вопрос

Можно ли установить двойные отношения в activerecord модели через generate scaffold командование?

Например, если у меня был User модель и а PrivateMessage модель, таблица PM должна отслеживать обоих sender а также recipient.

Очевидно, что для единых отношений я бы просто сделал это:

ruby script/generate scaffold pm title:string content:string user:references

Есть ли аналогичный способ настройки двух отношений?

Кроме того, есть ли в любом случае настроить псевдонимы для отношений?

Так что вместо того, чтобы говорить:

@message.user

Вы можете использовать что -то вроде:

@message.sender или же @message.recipient

Любой совет был бы очень признателен.

Спасибо.

Это было полезно?

Решение

Добавьте это в свою модель

has_one :sender, :class_name => "User"
has_one :recipient, :class_name => "User"

И вы можете позвонить @message.sender а также @message.recipient и оба ссылка на модель пользователя.

Вместо user:references В вашей команде Generate вам понадобится sender:references а также recipient:references

Другие советы

Вот полный ответ на этот вопрос, если люди, посещающие этот вопрос, являются новыми в Ruby на Rails, и с трудом складываются все вместе (как я был, когда я впервые изучил это).

Некоторые части решения происходят в ваших миграциях, а некоторые в ваших моделях:

Миграция

class CreatePrivateMessages < ActiveRecord::Migration
  def change
    create_table :private_messages do |t|
      t.references :sender
      t.references :recipient
    end
    # Rails 5+ only: add foreign keys
    add_foreign_key :private_messages, :users, column: :sender_id, primary_key: :id
    add_foreign_key :private_messages, :users, column: :recipient_id, primary_key: :id
  end
end

Здесь вы указываете, что в этой таблице есть два столбца, которые будут упоминаться как: отправитель и: получатель и которые содержат ссылки на другую таблицу. Rails фактически создаст для вас столбцы под названием «Sender_id» и «Receient_id». В нашем случае каждый из них будет ссылаться на строки в таблице пользователей, но мы указываем это в моделях, а не в миграциях.

Модели

class PrivateMessage < ActiveRecord::Base
  belongs_to :sender, :class_name => 'User'
  belongs_to :recipient, :class_name => 'User'
end

Здесь вы создаете свойство в модели PrivateMessage с именем: отправитель, а затем указываете, что это свойство связано с пользовательским классом. Rails, увидев «принадлежности_TO: отправитель», будет искать столбец в вашей базе данных под названием «sender_id», который мы определили выше, и использовать его для хранения иностранного ключа. Тогда вы делаете то же самое для получателя.

Это позволит вам получить доступ к своему отправителю и получателю, оба случая пользовательской модели, через экземпляр модели Privatemessage, например:

@private_message.sender.name
@private_message.recipient.email

Вот ваша пользовательская модель:

class User < ActiveRecord::Base
  has_many :sent_private_messages, :class_name => 'PrivateMessage', :foreign_key => 'sender_id'
  has_many :received_private_messages, :class_name => 'PrivateMessage', :foreign_key => 'recipient_id'
end

Здесь вы создаете свойство в модели пользователя с именем: sent_private_messages, указав, что это свойство связано с моделью Privatemessage, и что внешний ключ в модели Privatemessage, которая связывает его с этим свойством, называется «sender_id». Тогда вы делаете то же самое для полученных личных сообщений.

Это позволяет вам получить всех пользователей отправлять или получать личные сообщения, делая что -то подобное:

@user.sent_private_messages
@user.received_private_messages

Выполнение любого из них вернет массив экземпляров модели Privatemessage.

....

Привет, чтобы оба побочных отношения сделали, как реже в ваших моделях:

class Message < ActiveRecord::Base

 belongs_to     :sender,
                :class_name => "User",
                :foreign_key  => "sender_id"

 belongs_to     :recipient,
                :class_name => "User",
                :foreign_key  => "recipient_id" 
end

class User < ActiveRecord::Base

  has_many      :sent, 
                :class_name => "Message",
                :foreign_key  => "sent_id"

  has_many      :received, 
                :class_name => "Message", 
                :foreign_key  => "received_id"
end

Надеюсь, это вам поможет ...

Приведенные выше ответы, хотя и отличные, не создают ограничения иностранного ключа в базе данных, вместо этого создавая только индексы и столбцы Bigint. Чтобы убедиться, что ограничение иностранного ключа соблюдается, добавьте следующее к миграции:

class CreatePrivateMessages < ActiveRecord::Migration[5.1]
    def change
        create_table :private_messages do |t|
          t.references :sender
          t.references :recipient
        end

        add_foreign_key :private_messages, :users, column: :sender_id, primary_key: :id
        add_foreign_key :private_messages, :users, column: :recipient_id, primary_key: :id
    end
end

Это гарантирует, что индексы будут созданы на sender_id а также recipient_id а также ограничения внешнего ключа в базе данных, которую вы используете.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top