[英]Rails find_or_create_by more than one attribute?
在活動記錄中有一個名為find_or_create_by的方便動態屬性:
Model.find_or_create_by_<attribute>(:<attribute> => "")
但是,如果我需要通過多個屬性find_or_create呢?
假設我有一個模型來處理Group和Member之間的M:M關系,稱為GroupMember。 我可以有很多實例,其中member_id = 4,但我不想要多於一次的實例,其中member_id = 4和group_id = 7.我正在試圖弄清楚是否可以這樣做:
GroupMember.find_or_create(:member_id => 4, :group_id => 7)
我意識到可能有更好的方法來處理這個問題,但我喜歡find_or_create這個想法的便利性。
可以使用and
連接多個屬性:
GroupMember.find_or_create_by_member_id_and_group_id(4, 7)
(如果您不想立即保存記錄,請使用find_or_initialize_by
)
編輯:上面的方法在Rails 4中已棄用。新的方法是:
GroupMember.where(:member_id => 4, :group_id => 7).first_or_create
和
GroupMember.where(:member_id => 4, :group_id => 7).first_or_initialize
編輯2:並非所有這些都只是屬於特定屬性的rails。
https://github.com/rails/rails/blob/4-2-stable/guides/source/active_record_querying.md
例
GroupMember.find_or_create_by_member_id_and_group_id(4, 7)
成為
GroupMember.find_or_create_by(member_id: 4, group_id: 7)
對於偶然發現此線程但需要查找或創建具有可能根據具體情況而變化的屬性的對象的其他任何人,請將以下方法添加到您的模型中:
# Return the first object which matches the attributes hash
# - or -
# Create new object with the given attributes
#
def self.find_or_create(attributes)
Model.where(attributes).first || Model.create(attributes)
end
優化提示:無論您選擇哪種解決方案,請考慮為最常查詢的屬性添加索引。
在Rails 4中你可以這樣做:
GroupMember.find_or_create_by(member_id: 4, group_id: 7)
並使用where
的不同:
GroupMember.where(member_id: 4, group_id: 7).first_or_create
這將在GroupMember.where(member_id: 4, group_id: 7)
上調用create
:
GroupMember.where(member_id: 4, group_id: 7).create
與此相反,在find_or_create_by(member_id: 4, group_id: 7)
將調用create
於GroupMember
:
GroupMember.create(member_id: 4, group_id: 7)
請在rails / rails上查看此相關提交 。
通過將塊傳遞給find_or_create
,您可以傳遞將在創建新對象時添加到對象的其他參數。 如果要驗證是否存在未搜索的字段,則此選項非常有用。
假設:
class GroupMember < ActiveRecord::Base
validates_presence_of :name
end
然后
GroupMember.where(:member_id => 4, :group_id => 7).first_or_create { |gm| gm.name = "John Doe" }
將創建名為“John Doe”的新GroupMember,如果找不到具有member_id 4
and group_id 7
你可以做:
User.find_or_create_by(first_name: 'Penélope', last_name: 'Lopez')
User.where(first_name: 'Penélope', last_name: 'Lopez').first_or_create
或者只是初始化:
User.find_or_initialize_by(first_name: 'Penélope', last_name: 'Lopez')
User.where(first_name: 'Penélope', last_name: 'Lopez').first_or_initialize
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.