Rails:拥有并且属于许多(HABTM) – 创建关联而不创建其他记录

在Google上花了一整天,但找不到答案。 :\

我在用户和Core_Values之间有HABTM关系。

class CoreValue < ActiveRecord::Base has_and_belongs_to_many :users class User < ActiveRecord::Base has_and_belongs_to_many :core_values 

在我的控制器中,我需要做两件事:

  1. 如果CoreValue不存在,请创建一个新的并将其与给定的用户ID相关联,并且
  2. 假设我知道特定的CoreValue确实存在,则创建关联而不创建任何新的CoreValues或Users

对于#1,我有这个工作:

 User.find(current_user.id).core_values.create({:value => v, :created_by => current_user.id}) 

这将创建一个新的CoreValue:value和:created_by并创建关联。

对于#2,我尝试了一些东西,但似乎不太可能只创建关联。

谢谢你的帮助!

您可以使用非常有用的find_or_create方法find_or_create执行此操作。 find_or_create将首先尝试查找记录,如果它不存在,则创建它。 像这样的东西应该做的伎俩:

 core_value = CoreValue.find_or_create_by_value(v, :created_by => current_user.id) current_user.core_values << core_value 

一些说明:

  • 第一行将找到或创建值v 。 如果它不存在并且已创建,则会将created_by设置为current_user.id
  • 不需要执行User.find(current_user.id) ,因为它将返回与current_user相同的对象。
  • current_user.core_values是一个数组,您可以使用<<轻松地为其添加另一个值。

为简洁起见,以下内容与上面的代码示例相同:

 current_user.core_values << CoreValue.find_or_create_by_value(v, :created_by => current_user.id) 

在您的用户模型中添加方法:

 class User < ActiveRecord::Base def assign_core_value(v) core_values.find_by_name(v) || ( self.core_values << CoreValue.find_or_create_by_name(:name => v, :created_by => self)).last end end 

assign_core_value方法满足要求1,2并返回分配给用户的核心值(具有给定名称)。

现在您可以执行以下操作:

 current_user.assign_core_value(v) 

注1

方法逻辑如下:

1)检查CoreValue是否已与用户关联。 如果是这样,则不执行任何操作,则返回核心值。

2)检查具有给定名称的CoreValue是否存在。 如果没有创建CoreValue。 将核心值(创建/找到)与用户相关联。

Active Record已经为您提供了一种方法。 在你的情况下,

 val = CoreValue.find_by_value(v) current_user.core_values << val 

您也可以通过这种方式传递大量对象。 将创建所有关联

请查看此以获取更多信息