Rails - 使用同一模型创建和验证多对多关系?

时间:2016-07-05 00:08:37

标签: ruby-on-rails validation

这可能是一个非常简单的问题,但我一直在网上搜索大约一个小时,我无法找到问题的答案。通过以下内容应该清楚我对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文档中找到答案,我一直在学习。

1 个答案:

答案 0 :(得分:1)

我对此问题的初步印象与您的关联有关。对我来说,一个用户有很多敌人和很多朋友。

朋友属于用户

敌人属于用户

在这种情况下,不确定多对多关系是否有意义。也许这就是为什么你很难在网上找到答案的原因。只是我的两分钱。

相关问题