这可能是一个非常简单的问题,但我一直在网上搜索大约一个小时,我无法找到问题的答案。通过以下内容应该清楚我对Rails很新,所以我的术语和解释可能有点令人困惑。
假设我在Rails上制作社交媒体应用,其中一个模型是用户。我想创建一个多对多的关系,称为“朋友”,它将两个用户链接在一起。让我们说在这种情况下,我也希望在两个被称为“敌人”的用户之间建立多对多。
这完全是假设的,但这个想法与我正在使用的东西相同。
因为用户可以有很多朋友和敌人,但是许多朋友和敌人,我会使用:
class User < ActiveRecord::Base
has_and_belongs_to_many :users #this should be the friends association
has_and_belongs_to_many :users #this should be the enemies association
end
现在我猜我不能这样做,因为我必须有两个名为users_users的表。那么,我转到:
class User < ActiveRecord::Base
has_and_belongs_to_many(:users, join_table: 'friends',
foreign_key: 'user_id', associate_foreign_key: 'friend_id')
end
对敌人表有类似的陈述。现在,我的问题是我想要一个用户在注册时可以使用的表单,他们可以输入他们的信息(这是用户对象的详细信息),并列出他们的朋友和敌人。
因为用户不会为他们的朋友或敌人拥有数据库ID密钥,所以他们必须输入用户的名字。这很好,但因为名称也是一个唯一的密钥,由验证保证。
但是,如果用户输入朋友的名字,如果朋友不存在,我就无法加入这两个人。所以,我使用的自定义验证类看起来像这样:
class FriendValidator < ActiveModel::Validator
def validate(object)
#lookup user and throw error if not found.
end
end
将访问变量(object.friends)和(object.enemies)
对敌人有类似的东西。因此,在我的has_and_belongs_to_many语句之上,我有一些行说:
attr_accessor :friends, :enemies #these are attrs because they don't exist within the model's db
validates_with FriendValidator
当我使用erb创建表单时,我有标准的form_for块
<%= form_for(@user) do |f| %>
在我看来,我不能坚持
<%= f.text_area :friends %>
因为朋友实际上不会传递给User对象,而是一个单独的表。 (但我可以吗?因为attr_accessor是在用户的模型类中声明的吗?)
所以现在,我们遇到了我的主要问题。我有两个多对多的表,其模型与其自己的模型类,我不知道如何确保验证类将采取两个属性,查找并抛出必要的错误,然后添加一行到使用用户的id连接表,而不是输入的字符串。我应该使用哪些表单字段将输入传递到正确的位置?我在哪里更改控制器方法,以便将输入发送到连接表而不是用户对象?
这绝对是一个非常具体的情况,所以我无法在Rails文档中找到答案,我一直在学习。
答案 0 :(得分:1)
我对此问题的初步印象与您的关联有关。对我来说,一个用户有很多敌人和很多朋友。
朋友属于用户
敌人属于用户
在这种情况下,不确定多对多关系是否有意义。也许这就是为什么你很难在网上找到答案的原因。只是我的两分钱。