Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails - How to use Find Or Create

I have the following:

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

How can I update that to be find_or_create, so that if this record already exists, it's assigned to @permission, and if it doesn't exist, the record is created?

like image 259
AnApprentice Avatar asked Apr 20 '11 15:04

AnApprentice


People also ask

What is create in Rails?

create saves to the database and returns true or false depending on model validations. create! saves to the database but raises an exception if there are errors in model validations (or any other error). Follow this answer to receive notifications.

What is the difference between Create and new in Rails?

5.1 CreateThe new method will return a new object while create will return the object and save it to the database.

Is ActiveRecord an ORM?

ActiveRecord is an ORM. It's a layer of Ruby code that runs between your database and your logic code.

How do I search in Ruby on Rails?

Querying the Database Ruby on Rails doesn't actually have a module for search specifically. Active Record gives you a nice ORM to query data but doesn't have any helper methods to handle search. So we actually need to write a tiny bit of raw SQL and put that into Active Record's where method to make this work.


2 Answers

While the accepted answer is correct it's important to note that in Rails 4 this syntax will be changing (and the hash syntax). You should be writing the following:

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

Which actually looks much closer to your original method! See the sub-section Deprecated Finders for more details.

like image 165
Gavin Miller Avatar answered Oct 09 '22 01:10

Gavin Miller


Related topic:

find_or_create_by in Rails 3 and updating for creating records

You can extend ActiveRecord with your own update_or_create method (see related topic) and then you can use this

@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

Or you can use find_or_create_by... method:

@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
like image 30
fl00r Avatar answered Oct 09 '22 01:10

fl00r