Rails - 如何使用查找或创建

时间:2011-04-20 15:58:36

标签: ruby-on-rails ruby ruby-on-rails-3

我有以下内容:

@permission = @group.permissions.create(
  :user_id => @user.id,
  :role_id => 2,
  :creator_id => current_user.id)

如何将其更新为find_or_create,以便如果此记录已存在,则将其分配给@permission,如果该记录不存在,则会创建记录?

4 个答案:

答案 0 :(得分:51)

虽然accepted answer is correct值得注意的是,在Rails 4中,这种语法将会改变(以及散列语法)。您应该写下以下内容:

@permission = Permission.where(
  user_id: @user.id, 
  role_id: 2, 
  creator_id: current_user.id).first_or_create

实际上看起来更接近原始方法!有关详情,请参阅Deprecated Finders小节。

答案 1 :(得分:19)

相关主题:

  

find_or_create_by in Rails 3 and updating for creating records

您可以使用自己的update_or_create方法扩展ActiveRecord(请参阅相关主题),然后您可以使用此

@permission = Permission.update_or_create_by_user_id_and_role_id_and_creator_id(@user.id, 2, current_user.id) do |p|
  p.group_id = @group.id
end

或者您可以使用find_or_create_by...方法:

@permission = Permission.find_or_create_by_user_id_and_role_id_and_creator_id(@user.id, 2, current_user.id)
@permission.group = @group
@permission.save

答案 2 :(得分:6)

我正在使用版本化答案更新问题。因为它很重要。


Rails 4(docs

有几种方法可以找到或创建"一个对象,一个是find_or_create_by(args)

Client.find_or_create_by(email: "bambam@flinstones.com", phone: "4255551212")

社区首选方式正在使用where

client = Client.where(email: "bambam@flinstones.com", phone: "4255551212").first_or_create

然后你可以做类似的事情:

client = Client.where(client_params.slice(:email, :phone)).first_or_create
client.update(client_params)

Rails 3(docs

  

假设您要查找名为“Andy”的客户端,如果没有,   创建一个并另外将其locked属性设置为false。您可以   通过运行来完成:

client = Client.where(:first_name => 'Andy').first_or_create(:locked => false)
# => #<Client id: 1, first_name: "Andy", orders_count: 0, locked: false, created_at: "2011-08-30 06:09:27", updated_at: "2011-08-30 06:09:27">

答案 3 :(得分:2)

或者如果你有很多字段可以填写,你想尝试这个:

conditions = { :user_id => @user.id, 
               :role_id => 2,
               :creator_id => current_user.id }

    @permission = group.permissions.find(:first, :conditions => conditions) || group.permissions.create(conditions)

看到这篇文章: How can I pass multiple attributes to find_or_create_by in Rails 3?