質問

で二重の関係を設定することは可能ですか activerecord を介したモデル generate scaffold 指図?

たとえば、私が持っていた場合 User モデルとa PrivateMessage モデル、PMテーブルは両方を追跡する必要があります senderrecipient.

明らかに、単一の関係のために、私はこれを行うだけです:

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

2つの関係を設定する同様の方法はありますか?

また、とにかく関係のエイリアスをセットアップすることはありますか?

だから言うのではなく:

@message.user

次のようなものを使用できます。

@message.sender また @message.recipient

どんなアドバイスでも大歓迎です。

ありがとう。

役に立ちましたか?

解決

これをモデルに追加します

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

そして、あなたは電話することができます @message.sender@message.recipient 両方ともユーザーモデルを参照します。

それ以外の user:references 生成コマンドに必要なコマンドが必要です sender:referencesrecipient:references

他のヒント

この問題に対する完全な答えは、この質問にアクセスしている人々がRuby on 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

ここでは、このテーブルには、送信者と:受信者と別のテーブルへの参照を保持する2つの列があることを指定しています。 Railsは、実際に「Sender_id」と「Reciontient_id」と呼ばれる列を作成します。私たちの場合、ユーザーテーブルの各参照行が行われますが、移行ではなくモデルでそれを指定します。

モデル

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

ここでは、名前が付けられたprivatemessageモデルにプロパティを作成しています:送信者、次にこのプロパティがユーザークラスに関連していることを指定します。 Railsは、「belongs_to:sender」を見て、上記で定義した「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

ここでは、このプロパティが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_idrecipient_id 使用しているデータベースの外部キーの制約も同様です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top