Ruby on rails – 引用同一模型两次?
是否有可能通过generate scaffold
命令在activerecord
模型中build立双重关系?
例如,如果我有一个User
模型和一个PrivateMessage
模型,pm表将需要跟踪sender
和recipient
。
显然,对于一个单一的关系,我只是这样做:
ruby script/generate scaffold pm title:string content:string user:references
有没有类似的方式来build立两个关系?
另外,有没有build立关系的别名?
所以而不是说:
@message.user
你可以使用像这样的东西:
@message.sender
或@message.recipient
任何build议将不胜感激。
谢谢。
将此添加到您的模型
has_one :sender, :class_name => "User" has_one :recipient, :class_name => "User"
你可以调用@message.sender
和@message.recipient
,同时引用User模型。
而不是user:references
您的生成命令中的user:references
,你需要sender:references
和recipient:references
这里是对这个问题的完整答案,以防万一访问这个问题的人对Ruby on Rails不熟悉,而且把所有的东西都放在一起(就像我第一次看到这个时)。
解决scheme的一些部分发生在您的迁移中,一些发生在您的模型中:
迁移
class CreatePrivateMessages < ActiveRecord::Migration create_table :private_messages do |t| def up 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会为你创build一个名为“sender_id”和“recipient_id”的列。 在我们的例子中,它们将引用Users表中的行,但是我们在模型中指定,而不是在迁移中。
楷模
class PrivateMessage < ActiveRecord::Base belongs_to :sender, :class_name => 'User' belongs_to :recipient, :class_name => 'User' end
在这里,您将在名为sender的PrivateMessage模型上创build一个属性,然后指定该属性与User类相关。 看到“belongs_to:sender”的Rails将在你的数据库中寻找一个名为“sender_id”的列,并且使用它来存储外键。 然后你对收件人完全一样。
这将允许您通过一个PrivateMessage模型的实例来访问您的发件人和收件人,这两个User模型的实例都是这样的:
@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的用户模型上创build一个属性,指定该属性与PrivateMessage模型相关,并且将PrivateMessage模型中与该属性相关的外键称为“sender_id”。 那么你对收到的私人信息做同样的事情。
这可以让你通过做这样的事情得到所有的用户发送或接收私人信息:
@user.sent_private_messages @user.received_private_messages
做这些将会返回一个PrivateMessage模型的实例的数组。
….
嗨那里有双方关系做你的两个模型波纹pipe:
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
我希望这可以帮助你…
上面的答案虽然很好,但不会在数据库中创build外键约束,而只能创build索引和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
上创build索引以及在您使用的数据库中的外键约束。