2011-01-19 42 views
15

在Google上呆了一整天,但找不到答案。 :\Rails:擁有並且屬於很多(HABTM) - 創建關聯而不創建其他記錄

我在用戶和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或用戶

#1建立關聯,我得到這個工作:

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

這創建了一個新的CoreValue:value和:created_by並創建關聯。

對於#2,我嘗試了一些東西,但似乎不能創建關聯只。

感謝您的幫助!

回答

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_bycurrent_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) 
+0

謝謝!不知道core_values是一個數組 - 當然不知道添加到數組會創建一個INSERT。甜!如果記錄不存在,只能創建關聯的任何方式?我想看看數組方法,我猜?也許是current_user.core_values.include? – jmccartie 2011-01-19 01:16:02

+0

@jmccartie這可能是一種做法,是的。爲了澄清,我覺得我應該補充一點,`core_values`不是* always *數組 - 如你所知,你可以調用`core_values.create`這不是一個有效的數組方法。一個更好的定義是它「作爲一個陣列」。 – vonconrad 2011-01-19 01:38:09

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。將核心價值(創建/找到)與用戶關聯起來。

0

Active Record已經爲您提供了一種方法。在你的情況下,

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

你也可以這樣傳遞一些對象。所有協會將創建

檢查this瞭解更多信息