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

时间:2011-01-19 00:13:03

标签: ruby-on-rails activerecord has-and-belongs-to-many

在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或用户
  3. 对于#1,我有这个工作:

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

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

    对于#2,我尝试了一些事情,但似乎不能仅仅创建这种关联。

    感谢您的帮助!

3 个答案:

答案 0 :(得分:21)

您可以使用非常有用的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)

答案 1 :(得分:4)

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

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。将核心值(创建/找到)与用户关联。

答案 2 :(得分:0)

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

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

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

检查this以获取更多信息

相关问题