Ruby on Rails - 引用同一模型两次?

发布于 2024-08-17 21:10:30 字数 578 浏览 6 评论 0原文

是否可以通过generatescaffold命令在activerecord模型中设置双重关系?

例如,如果我有一个 User 模型和一个 PrivateMessage 模型,则 private_messages 表需要跟踪 sender>收件人

显然,对于单个关系,我只会这样做:

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

是否有类似的方法来建立两个关系?

另外,有没有办法为关系设置别名?

因此,不要说:

@message.user

您可以使用类似:

@message.sender@message.recipient

任何建议将不胜感激。

谢谢。

Is it possible to set up a double relationship in activerecord models via the generate scaffold command?

For example, if I had a User model and a PrivateMessage model, the private_messages table would need to keep track of both the sender and recipient.

Obviously, for a single relationship I would just do this:

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

Is there a similar way to set up two relations?

Also, is there anyway to set up aliases for the relations?

So rather than saying:

@message.user

You can use something like:

@message.sender or @message.recipient

Any advice would be greatly appreciated.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

坦然微笑 2024-08-24 21:10:30

这是这个问题的完整答案,以防访问这个问题的人对 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

这里您指定此表中有两列将被称为 :sender 和 :recipient 并保存对另一个表的引用。 Rails 实际上会为您创建名为“sender_id”和“recipient_id”的列。在我们的例子中,它们将各自引用 Users 表中的行,但我们在模型中指定,而不是在迁移中。

模型

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

这里您将在 PrivateMessage 模型上创建一个名为 :sender 的属性,然后指定该属性与 User 类相关。 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

这里,您将在名为 :sent_private_messages 的用户模型上创建一个属性,指定该属性与 PrivateMessage 模型相关,并且 PrivateMessage 模型上与该属性相关的外键称为“sender_id”。然后你对收到的私人消息做同样的事情。

这允许您通过执行以下操作来获取所有发送或接收私人消息的用户:

@user.sent_private_messages
@user.received_private_messages

执行其中任何一项操作都将返回 PrivateMessage 模型的实例数组。

....

Here's a complete answer to this issue, in case people visiting this question are new to Ruby on Rails and having a hard time putting everything together (as I was when I first looked into this).

Some parts of the solution take place in your Migrations and some in your Models:

Migrations

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

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 PrivateMessage < ActiveRecord::Base
  belongs_to :sender, :class_name => 'User'
  belongs_to :recipient, :class_name => 'User'
end

Here you are creating a property on the PrivateMessage model named :sender, then specifying that this property is related to the User class. Rails, seeing the "belongs_to :sender", 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 PrivateMessage model, like this:

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

Here is your User Model:

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

Here you are creating a property on the User Model named :sent_private_messages, specifying that this property is related to the PrivateMessage Model, and that the foreign key on the PrivateMessage model which relates it to this property is called 'sender_id'. Then you are doing the same thing for received private messages.

This allows you to get all of a users sent or received private messages by doing something like this:

@user.sent_private_messages
@user.received_private_messages

Doing either of these will return an array of instances of the PrivateMessage model.

....

欢你一世 2024-08-24 21:10:30

将其添加到您的模型中

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

,您可以调用 @message.sender@message.recipient 并引用 User 模型。

您需要 sender:referencesrecipient:references,而不是生成命令中的 user:references

Add this to your Model

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

And you are able to call @message.sender and @message.recipient and both reference to the User model.

Instead of user:references in your generate command, you'd need sender:references and recipient:references

呆° 2024-08-24 21:10:30

你好呀
在您的两个模型中使双方关系如下:

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

我希望这对您有帮助......

hi there
to have both side relation do as bellow in your both models:

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

I hope this help you...

慕巷 2024-08-24 21:10:30

上面的答案虽然很好,但不会在数据库中创建外键约束,而是仅创建索引和 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 以及外键上创建索引您正在使用的数据库中的约束。

The above answers, while excellent, do not create foreign key constraints in the database, instead only creating indexes and bigint columns. To ensure that the foreign key constraint is enforced, add the following to your migration:

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

This will ensure that the indices get created on the sender_id and recipient_id as well as the foreign key constraints in the database you're using.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文