Maybe some Ruby experts out there can shed some light on how activerecord
know to do an insert
or update
when calling save()
. What is the logic behind it? Does it check to see if the primary key is blank or something and if so does an insert
, if not an update
?
Active Record facilitates the creation and use of business objects whose data requires persistent storage to a database. It is an implementation of the Active Record pattern which itself is a description of an Object Relational Mapping system.
ActiveRecord::Base indicates that the ActiveRecord class or module has a static inner class called Base that you're extending. Edit: as Mike points out, in this case ActiveRecord is a module...
Returns a new relation, which is the result of filtering the current relation according to the conditions in the arguments.
ActiveRecord is an ORM. It's a layer of Ruby code that runs between your database and your logic code.
Whilst it's fine for some people to say "RTFM" I rather the more walk-through-but-still-entirely-useless-when-Rails-3-comes-out-and-changes-everything response:
How it works in Rails 2.3 (aka "today")
save
calls create_or_update
which looks like this:
def create_or_update
raise ReadOnlyRecord if readonly?
result = new_record? ? create : update
result != false
end
You can ignore the first line of this method as it only raises an error if the record is readonly (it isn't usually, but in the case of joins it may be). What we are interested in here is the second and third lines inside the method.
The second line calls new_record?
which is defined as this:
# Returns true if this object hasn't been saved yet -- that is, a record for the object doesn't exist yet; otherwise, returns false.
def new_record?
@new_record || false
end
And the variable @new_record
is set when the initialize
(new
calls initialize
, and gives us a new object, some background Ruby-fu here) method is called.
So if this @new_record
is true
it'll call create
and if it's false it'll call update
which brings us to what you're after, I think.
Furthermore, when you find a record it does not call initialize
and therefore does not set @new_record
. If you noticed, the code behind new_record?
was @new_record || false
, meaning it will return false if @new_record
was not set.
Let's say for example you want to find the last Forum
record, so you would do Forum.last
.
last
method on the Forum
class, which inherits from ActiveRecord::Baselast
calls the find
class method.find
calls find_last
find_last
calls find_initial
find_initial
calls find_every
find_every
calls find_by_sql
find_by_sql
calls instantiate
You'll see here that nowhere along this change is @new_record
set and thus any record obtained by find
will not be a new record.
Hope this helps you understand.
It principaly relies on the new_record? method.
This method returns true if it's a new record and false if it's not.
In fact it's not really hard.
new_record?
can direcly return false.Model.new
), new_record?
will return true. It's a new record.@new_record
gets updated. new_record?
won't return true anymore.To see when it happens, go to ActiveRecord::Base, line 2911
self.id ||= new_id
@new_record = false
id
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With