Ruby on Rails-引用同一型号两次?
-
20-09-2019 - |
题
是否可以在 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
在您的生成命令中,您需要 sender:references
和 recipient: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
在这里,您指定该表中有两个列,将称为:发件人和:收件人,并且将其引用到另一个表中。 Rails实际上将为您创建名为“ Sender_ID”和“ conferient_id”的列。在我们的情况下,他们将每个参考用户表中的参考行,但我们在模型中而不是迁移中指定。
楷模
class PrivateMessage < ActiveRecord::Base
belongs_to :sender, :class_name => 'User'
belongs_to :recipient, :class_name => 'User'
end
在这里,您是在名为:发送者的私有信息模型上创建属性,然后指定此属性与用户类有关。 Rails,看到“属于_to:sender”,将在您的数据库中寻找一个名为“ sender_id”的列,我们在上面定义了该列,并将其用来存储外键。然后,您为收件人做完全相同的事情。
这将使您能够通过私人信息模型的实例访问用户模型的两个实例,例如:
@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
在这里,您是在名为:send_private_messages的用户模型上创建属性,指定此属性与私人信息模型相关,并且将其与此属性相关的私有信息模型上的外键称为'sender_id'。然后,您正在为收到的私人消息做同样的事情。
这使您可以通过执行类似的操作来获取所有发送或接收的用户:
@user.sent_private_messages
@user.received_private_messages
这样做的任何一个都将返回私人信息模型的一系列实例。
....
嗨,在两个模型中都有两种关系的关系:
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
以及您正在使用的数据库中的外键约束。