tyb*_*103 199 activerecord many-to-many model ruby-on-rails dynamic-attributes
在活动记录中有一个名为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)
Run Code Online (Sandbox Code Playgroud)
我意识到可能有更好的方法来处理这个问题,但我喜欢find_or_create这个想法的便利性.
x1a*_*1a4 461
多个属性可以与and:
GroupMember.find_or_create_by_member_id_and_group_id(4, 7)
Run Code Online (Sandbox Code Playgroud)
(find_or_initialize_by如果您不想立即保存记录,请使用)
编辑:上面的方法在Rails 4中已弃用.新的方法是:
GroupMember.where(:member_id => 4, :group_id => 7).first_or_create
Run Code Online (Sandbox Code Playgroud)
和
GroupMember.where(:member_id => 4, :group_id => 7).first_or_initialize
Run Code Online (Sandbox Code Playgroud)
编辑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)
Run Code Online (Sandbox Code Playgroud)
成为
GroupMember.find_or_create_by(member_id: 4, group_id: 7)
Run Code Online (Sandbox Code Playgroud)
Mar*_*rco 32
对于偶然发现此线程但需要查找或创建具有可能根据具体情况而变化的属性的对象的其他任何人,请将以下方法添加到您的模型中:
# 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
Run Code Online (Sandbox Code Playgroud)
优化提示:无论您选择哪种解决方案,请考虑为最常查询的属性添加索引.
Jua*_*tas 29
在Rails 4中你可以这样做:
GroupMember.find_or_create_by(member_id: 4, group_id: 7)
Run Code Online (Sandbox Code Playgroud)
使用where方式不同:
GroupMember.where(member_id: 4, group_id: 7).first_or_create
Run Code Online (Sandbox Code Playgroud)
这将调用create上GroupMember.where(member_id: 4, group_id: 7):
GroupMember.where(member_id: 4, group_id: 7).create
Run Code Online (Sandbox Code Playgroud)
相反,在find_or_create_by(member_id: 4, group_id: 7)将调用create上GroupMember:
GroupMember.create(member_id: 4, group_id: 7)
Run Code Online (Sandbox Code Playgroud)
请在rails/rails上查看此相关提交.
小智 15
通过传递一个块find_or_create,您可以传递将添加到对象的其他参数(如果它是新创建的).如果要验证是否存在未搜索的字段,则此选项非常有用.
假设:
class GroupMember < ActiveRecord::Base
validates_presence_of :name
end
Run Code Online (Sandbox Code Playgroud)
然后
GroupMember.where(:member_id => 4, :group_id => 7).first_or_create { |gm| gm.name = "John Doe" }
Run Code Online (Sandbox Code Playgroud)
将创建一个名为"John Doe"的新GroupMember,如果找不到的话 member_id 4 and group_id 7
你可以做:
\n\nUser.find_or_create_by(first_name: 'Pen\xc3\xa9lope', last_name: 'Lopez')\nUser.where(first_name: 'Pen\xc3\xa9lope', last_name: 'Lopez').first_or_create\nRun Code Online (Sandbox Code Playgroud)\n\n或者只是初始化:
\n\nUser.find_or_initialize_by(first_name: 'Pen\xc3\xa9lope', last_name: 'Lopez')\nUser.where(first_name: 'Pen\xc3\xa9lope', last_name: 'Lopez').first_or_initialize\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
99032 次 |
| 最近记录: |