2014-01-17 83 views
21

增加更多的價值舉個例子如下:Rails的第一或一個值初始化,但如果創建

GroupMember.where(:member_id => 4).first_or_initialize

如果我想這樣說這個 -

如果GroupMember用4的member_id存在,「找到它」。否則,請創建一個Group_id爲4且group_id爲7的GroupMember。

所以我希望上面的語句只檢查member_id - 但是如果它不存在,我希望它創建一個GroupMember與多個屬性。我會如何寫?我正在使用rails 4.0。

回答

32

這是我使用的參考 - http://apidock.com/rails/ActiveRecord/Relation/first_or_initialize

該方法的來源狀態:

def first_or_initialize(attributes = nil, &block) 
    first || new(attributes, &block) 
end 

因此,如果找不到記錄 - 它會初始化一個新記錄並傳遞給一個塊。

您可以使用它:

GroupMember.where(:member_id => 4).first_or_initialize do |member| 
    member.group_id = 7 
end 

它將爲只新記錄執行塊。

+0

非常感謝,正是我所期待的 – Tallboy

1

使用

find_or_initialize_by_member_id_and_group_id(member_id, group_id) 

,你都將通過member_id和組ID創建GroupMember uniq的。 (by只用過一次)

我不確定這個聲明是否適用於Rails 4。它正在使用Rails 3.2

請檢查軌道控制檯上面的語句,並讓我知道它是否工作不。

更新:

按照錯誤控制檯代碼必須是:

GroupMember.find_or_initialize_by(member_id: member_id, group_id: group_id) 

請驗證更改工程或不

+0

Rails控制檯返回: '退化警告:此動態方法已棄用。請使用改爲Post.find_or_initialize_by(名稱:'foo')。 (從(irb)的irb_binding調用:17)' – Luigi

+0

請參考上面的更新並讓我知道輸出。 – Rubyist

+0

原始版本技術上在Rails 4中工作(到目前爲止),它僅顯示提及的棄用警告luigi,並且仍然返回相同的數據。 @Luigi因此,如果/當舊的'find_or_initialize_by ...'出現時,您一定要使用第二版Rubyist發佈以避免出現問題。在未來版本的Rails中完全刪除了版本。 –

0

嘗試用這種Post.find_or_create_by(member_id: member_id, group_id: group_id)

38

這也適用於:

GroupMember.where(member_id: 4).first_or_initialize(group_id: 7) 

傳遞給first_or_initialize的屬性時,它會創建一個新的記錄僅用於,他們正在與來自「裏的屬性合併「條款。

+3

IMO應該是被接受的答案。 – thekingoftruth

+0

你在代碼中提到的是「合併」嗎? – Dan

+0

它發生在ActiveRecord :: Relation#new中,它構建一個嵌套的作用域 - where子句參數在外部作用域中,並且'first_or_initialize'參數進入新作用域,通過調用覆蓋外部作用域' scoping'。這不是非常明顯,但它發生。 – scottb

相關問題