first_or_create
- 1.0.0
- 1.1.6
- 1.2.6
- 2.0.3
- 2.1.0
- 2.2.1
- 2.3.8
- 3.0.0
- 3.0.9
- 3.1.0
- 3.2.1 (0)
- 3.2.8 (0)
- 3.2.13 (0)
- 4.0.2 (-38)
- 4.1.8 (0)
- 4.2.1 (0)
- 4.2.7 (0)
- 4.2.9 (0)
- 5.0.0.1 (0)
- 5.1.7 (0)
- 5.2.3 (0)
- 6.0.0 (0)
- 6.1.3.1 (0)
- 6.1.7.7 (0)
- 7.0.0 (0)
- 7.1.3.2 (0)
- 7.1.3.4 (0)
- What's this?
first_or_create(attributes = nil, options = {}, &block)
public
Tries to load the first record; if it fails, then create is called with the same arguments as this method.
Expects arguments in the same format as Base.create.
Examples
# Find the first user named Penélope or create a new one. User.where(:first_name => 'Penélope').first_or_create # => <User id: 1, first_name: 'Penélope', last_name: nil> # Find the first user named Penélope or create a new one. # We already have one so the existing record will be returned. User.where(:first_name => 'Penélope').first_or_create # => <User id: 1, first_name: 'Penélope', last_name: nil> # Find the first user named Scarlett or create a new one with a particular last name. User.where(:first_name => 'Scarlett').first_or_create(:last_name => 'Johansson') # => <User id: 2, first_name: 'Scarlett', last_name: 'Johansson'> # Find the first user named Scarlett or create a new one with a different last name. # We already have one so the existing record will be returned. User.where(:first_name => 'Scarlett').first_or_create do |user| user.last_name = "O'Hara" end # => <User id: 2, first_name: 'Scarlett', last_name: 'Johansson'>
Find the First Instance in the Table. If None Exists, Create One.
Specify the data you’re looking for. If it exists in the table, the first instance will be returned. If not, then create is called.
If a block is provided, that block will be executed only if a new instance is being created. The block is NOT executed on an existing record.
Code example
MyStat.where(name: statistic_name).first_or_create do |statistic| statistic.value = calculate_percentage statistic.statistic_type = "percentage" end
Creates record by given attributes only if table is empty
This method first searches the table for ANY FIRST RECORD, not the one matching given attributes. If no record is found at all, it creates one using the specified attributes. This might be misunderstood in many cases.
RE: FALSE: Creates record by given attributes only if table is empty
Dino’s comment was almost certainly due to a misunderstanding of the API, a mistake I made myself the first time I used it, and one I’ve witnessed multiple others make as well.
The fact that this method takes an attributes parameter leads one to think the passed params are the criteria for the selection. At first glance it would appear it would be used like this:
User.first_or_create(email: 'derek@somwhere.com')
Where in reality this would grab the “first” record (say w/ email “john@smith.com”), and change its email to “derek@somwhere.com”, a fairly surprising action that doesn’t obviously fail, leading to some pretty subtle bugs.
In reality it should be used like this:
User.where(email: 'derek@somwhere.com').first_or_create
And the attributes param. isn’t used in 99% of use cases. (If at all - the provision for the block that executes only on create fully duplicates what the attributes parameter can do in a much more obvious way.)
IMHO this is simply a bad API that one just needs to be aware of. But it’s unfair to knock dino for what’s likely a highly common misreading.
RE: RE: FALSE: Creates record by given attributes only if table is empty
keredson is still a little off on the behavior.
>> Where in reality this would grab the “first” record (say w/ email “john@smith.com”), and change its email to “derek@somwhere.com”, a fairly surprising action that doesn’t obviously fail, leading to some pretty subtle bugs.
This isn’t right, as if you look at the source it calls: “first || create(attributes, &block)”
So in the example of:
User.first_or_create(email: 'derek@somwhere.com')
it would find the first user with any email, and return it. And thats it. The attributes passed in as params are only used in the event that first returns no matches, and create is called.
I’m using it in a way similar to:
Foo.where(bar: baz_params[:bar]).first_or_create(baz_params)
This will find the first Foo where bar is equal to the bar sent from baz_params. If none is found, it will create it. It’s useful for me when importing large amounts of data where I know there will be duplicate records.
SOCKET LIBRARY IN RUBY ON RAILS
There are basically two levels of accessing network services in case of rails .
The socket and network libraries are such important parts of integrating Ruby applications with the Internet and other communications-based environments.
One is through socket libraries provide low level access to connection oriented and connection-less protocols. Where user can implement client and server connection. Ruby is also having Network libraries that provide users a high level access to specific network protocols like FTP,HTTP and Etc.
At a low level, you can access the basic socket support in the underlying operating system, which allows you to implement clients and servers for both connection-oriented and connectionless protocols. Ruby also has libraries that provide higher-level access to specific application-level network protocols, such as FTP, HTTP, and so on.
What are Sockets?
Sockets are basically a bidirectional communications channel. Sockets may communicate within a process, between processes on the same machine, or between processes on different continents. Sockets can be implemented on different channels : Unix domain sockets, TCP, UDP, and so on. The socket library mainly provides specific classes and interface for handling a transports.
A SimpleClient:
Hereis a very basic client program which will open up a connection to a given port and given host. Ruby class TCPSocket provides open function to open a socket. The TCPSocket.open(hosname, port ) opens a TCP connection to hostname & theport.
Once socket is open, you can actually read that particular thing like IO object. When it’s done, just remember to close it, as you close that file. The following code connects to a given host and port, reads any available data from the socket, and then exits:
require ‘socket’ # Socket in standard library
hostname = ‘localhost’
port = 8080
s = TCPSocket.open(hostname, port)
while line = s.gets # Gets and Read the lines from the socket
puts line.chop # And print with platform line terminator end
s.close # socket Closed
A Simple Server: To write Internet servers, we basically use this TCPServer class. A TCPServer object is a factory for TCPSocket objects. Now call TCPServer.open(hostname, port function to specify a port for your service and create a TCPServer object. Next, call the accept method of the returned TCPServer object. This particular method waits till client connects to the port you specified above, and then returns a TCPSocket object that basically represents the connection to that client.
require ‘socket’ # Get sockets from stdlib server = TCPServer.open(8080) # Socket to listen on port 8080 loop { # Servers run forever
client = server.accept # Wait for a client to connect client.puts(Time.now.ctime) # Send the time to the client client.puts "Closing the connection. Bye!" client.close # Disconnect from the client
}
Now run this server in background and then run above client to see the result.
FALSE: Creates record by given attributes only if table is empty
I very much doubt that dino’s comment was ever correct, but it certainly isn’t correct now. The behavior liantics describes is correct.