Find_or_create_by: Active Record , Ruby on Rails
Updated: Mar 9
I am working on a project that I am very excited about!
I am creating a social media platform for animals. I like to keep my project ideas silly and fun
because it is hard to learn a new skill if you are working on a project that doesn't thrill you.
My relationships in my model are set up such that A Post cannot be created without a User.
I created ease with my project by allowing a person to create both a post and a user at the same time.
When I was attempting to create a new post in my application. I ran into an error on my backend.
My post was able to create, however, I was not able to create a user, or find a user properly.
My database would attempt to create a new user record, but would then fail.
My code looked like this originally:
In line 19, I am creating a User Instance. This is inside of my Posts Controller. Here I am saying that I only want to create a user if its name attribute is not found in my database.
I am using the Find_or_create_by method. This is a method to help search for data from what you pass in, and if its record is not found in your database, will create a new record.
The first argument is the attribute name, and its value.
Find_or_create_by accepts a block of code.
In the block that starts on line 20 I am specifiying the values that I want each attribute to be set to if this user is not found in the database.
Now the database is able to create a new user in the database with all of its attributes passed in through the form where the data was entered.
I kept getting an error where the database would INSERT a row to the table, but then it would rollback transaction.
The database was very confused because I was only passing it a name attribute, and so if it could not find the user record, it was unable to create a new user in the table with only the name attribute given.
In my posts controller, I have strong params set for users. What strong params do is make sure a user can only be created with the parameters I specified.
I only want to create a new user record in my database if the name attribute that was typed into my form does not match any of the names that are currently in my database.
When I create a User on my form I am passing 6 attributes. However, the only attribute I do not want repeated is the User's name.
I rewrote my code like so:
Here, In line 19 I am still looking for the name attribute, however, I am specifying what the database should compare that name to. It should be compared to the name attribute that gets entered into my form.
Now the database is able to create an entire User, with all of its params passed in as well as look for the name attribute in the entire object.
I am constantly searching through my database, and now there is an easier way to accomplish this task.
Hope you enjoyed this!