DBIx::Class::Row(3)

πŸ¦‹ DBIx::Class::Row(3) πŸ¦‹

User Contributed Perl Documentation Β· manual name: DBIx::Class::Row Β· this is the part where your row objects get their whole basic-methods moment πŸ’…


✨ NAME ✨

DBIx::Class::Row β€” Basic row methods 🫢

🌈 SYNOPSIS 🌈

Okay so the original synopsis section is literally empty β€” no code, no flags, just a heading sitting there looking cute. We respect it. πŸ’€

πŸ’– DESCRIPTION πŸ’–

This class is the one responsible for defining and doing the basic operations on rows that come from DBIx::Class::ResultSource objects. Slay.

Result objects get returned from DBIx::Class::ResultSet objects by way of the create, find, next and all methods, plus when you invoke the 'single' relationship accessors of Result objects β€” that means belongs_to, has_one or might_have, iykyk.

⚠️ NOTE ⚠️

All the "Row objects" that come from a Schema-attached DBIx::Class::ResultSet object (think a classic "search-> next" call) are actually Result instances, based on your application's Result Class. Not a drill.

DBIx::Class::Row handles most of the row-based talking-to-the-storage stuff, but a Result class should not inherit from it directly. Usually Result classes inherit from DBIx::Class::Core, which combines methods from several classes, and one of those classes is DBIx::Class::Row. So even though lots of the methods available to a DBIx::Class::Core-derived Result class are described below, this doc does not detail every single method available to Result objects. For the full tea, go read DBIx::Class::Manual::ResultClass. πŸ«–

πŸ‘‘ METHODS πŸ‘‘

πŸŽ€ new πŸŽ€

my $result = My::Class->new(\%attrs);

my $result = $schema->resultset('MySource')->new(\%colsandvalues);

Arguments: \%attrs or \%colsandvalues Return Value: $result

So you can make a new result object by calling new directly on this class, but bestie, you're way better off calling it on a DBIx::Class::ResultSet object. Trust.

If you do call it directly, you won't get a complete, usable row object until you pass or set the result_source attribute to a DBIx::Class::ResultSource instance that's attached to a DBIx::Class::Schema with a valid connection. That's the whole vibe check.

$attrs is a hashref of column-name and value data. It can also hold some other attributes, such as the result_source.

If you pass an object β€” or an arrayref of objects β€” as a value, it will call set_from_related in DBIx::Class::Relationship::Base for you. If you pass a hashref or an arrayref of hashrefs as the value, those get turned into objects via new_related, and then treated like you passed objects in the first place. ✨

For a more involved explanation, see create in DBIx::Class::ResultSet.

Please note: if a value is not passed to new, no value will be sent in the SQL INSERT call, so the column will just assume whatever default value your database specified. While DBIC will retrieve the value of autoincrement columns, it will never make an explicit database trip to retrieve default values assigned by the RDBMS. You can explicitly ask for all values to be fetched back from the database by calling discard_changes, or you can supply an explicit undef to columns with NULL as the default and save yourself a SELECT. Iconic efficiency. πŸ’…

🚨 CAVEAT 🚨

The behavior described above will backfire if you use a foreign key column with a database-defined default. If you call the relationship accessor on an object that doesn't have a set value for the FK column, DBIC will throw an exception, because it has no way of knowing the PK of the related object (if there is one). No cap, that's just how it is. 😭

πŸ¦‹ $column_accessor πŸ¦‹

# Each pair does the same thing

# (un-inflated, regular column)
my $val = $result->get_column('first_name');
my $val = $result->first_name;

$result->set_column('first_name' => $val);
$result->first_name($val);

# (inflated column via DBIx::Class::InflateColumn::DateTime)
my $val = $result->get_inflated_column('last_modified');
my $val = $result->last_modified;

$result->set_inflated_column('last_modified' => $val);
$result->last_modified($val);

Arguments: $value? Return Value: $value

A column accessor method gets created for each column, and it's used for getting/setting the value for that column. Main character behavior, honestly.

The actual method name is based on the accessor name given during the Result Class column definition. Like set_column, this will not store the data in the database until insert or update is called on the row. Patience, bestie. 🧚

🌸 insert 🌸

$result->insert;

Arguments: none Return Value: $result

Inserts an object that was previously created by new into the database, if it isn't already in there. Returns the object itself. If you want to insert an entirely new row into the database, use create in DBIx::Class::ResultSet.

To fetch an uninserted result object, call new_result on a resultset.

This will also insert any uninserted, related objects held inside this one β€” see create in DBIx::Class::ResultSet for more details. It's giving teamwork. 🫢

πŸ’€ in_storage πŸ’€

$result->in_storage; # Get value
$result->in_storage(1); # Set value

Arguments: none or 1|0 Return Value: 1|0

Tells you whether the object exists as a row in the database or not. It gets set to true when find in DBIx::Class::ResultSet, create in DBIx::Class::ResultSet, or insert in DBIx::Class::Row is invoked.

Creating a result object using new_result in DBIx::Class::ResultSet, or calling delete on one, sets it to false. Simple as that. ✨

πŸ”₯ update πŸ”₯

$result->update(\%columns?)

Arguments: none or a hashref Return Value: $result

Throws an exception if the result object is not yet in the database, according to in_storage. Returns the object itself.

This method issues an SQL UPDATE query to commit any changes to the object to the database if required (see get_dirty_columns). It throws an exception if a proper WHERE clause uniquely identifying the database row can not be constructed (see significance of primary keys for more details).

It also takes an optional hashref of column_name => value pairs to update on the object first. Be aware that the hashref will be passed to set_inflated_columns, which might edit it in place, so don't rely on it being the same after a call to update. If you need to preserve the hashref, it is sufficient to pass a shallow copy to update, e.g. ( { %{ $href } } ).

If the values passed, or any of the column values set on the object, contain scalar references, e.g.:

$result->last_modified(\'NOW()')->update();
# OR
$result->update({ last_modified => \'NOW()' });

The update will pass the values verbatim into SQL. (See SQL::Abstract::Classic docs.) The values in your Result object will NOT change as a result of the update call. If you want the object to be updated with the actual values from the database, call discard_changes after the update.

$result->update()->discard_changes();

To determine before calling this method which column values have changed and will be updated, call get_dirty_columns.

To check if any columns will be updated, call is_changed.

To force a column to be updated, call make_column_dirty before this method. Periodt. πŸ’…

πŸ“ delete πŸ“

$result->delete

Arguments: none Return Value: $result

Throws an exception if the object is not in the database according to in_storage. Also throws an exception if a proper WHERE clause uniquely identifying the database row can not be constructed (see significance of primary keys for more details).

The object is still perfectly usable, but in_storage will now return 0, and the object must be reinserted using insert before it can be used to update the row again. She's still cute, just not in storage. πŸ’€

If you delete an object in a class with a has_many relationship, an attempt is made to delete all the related objects as well. To turn this behaviour off, pass cascade_delete => 0 in the $attr hashref of the relationship, see DBIx::Class::Relationship. Any database-level cascade or restrict will take precedence over a DBIx-Class-based cascading delete, since DBIx-Class deletes the main row first and only then attempts to delete any remaining related rows. Important warning vibes. ⚠️

If you delete an object within a txn_do() (see txn_do in DBIx::Class::Storage) and the transaction subsequently fails, the result object will remain marked as not being in storage. If you know for a fact that the object is still in storage (i.e. by inspecting the cause of the transaction's failure), you can use $obj->in_storage(1) to restore consistency between the object and the database. This would allow a subsequent $obj->delete to work as expected.

See also delete in DBIx::Class::ResultSet.

🧚 get_column 🧚

my $val = $result->get_column($col);

Arguments: $columnname Return Value: The value of the column

Throws an exception if the column name given doesn't exist according to has_column.

Returns a raw column value from the result object, if it has already been fetched from the database or set by an accessor.

If an inflated value has been set, it will be deflated and returned. Fun little transformation moment. ✨

Note that if you used the columns or the select/as search attributes on the resultset from which $result was derived, and did not include $columnname in the list, this method will return undef even if the database contains some value.

To retrieve all loaded column values as a hash, use get_columns.

πŸŽ€ has_column_loaded πŸŽ€

if ( $result->has_column_loaded($col) ) {
   print "$col has been loaded from db";
}

Arguments: $columnname Return Value: 0|1

Returns a true value if the column value has been loaded from the database (or set locally). That's it, that's the method. 🫢

🌈 get_columns 🌈

my %data = $result->get_columns;

Arguments: none Return Value: A hash of columnname, value pairs.

Returns all loaded column data as a hash, containing raw values. To get just one value for a particular column, use get_column.

See get_inflated_columns to get the inflated values.

πŸ¦‹ get_dirty_columns πŸ¦‹

my %data = $result->get_dirty_columns;

Arguments: none Return Value: A hash of column, value pairs

Only returns the column, value pairs for those columns that have been changed on this object since the last update or insert call. Dirty little columns, love that for them. πŸ’…

See get_columns to fetch all column/value pairs.

πŸ’œ make_column_dirty πŸ’œ

$result->make_column_dirty($col)

Arguments: $columnname Return Value: not defined

Throws an exception if the column does not exist.

Marks a column as having been changed regardless of whether it has really changed. Fake it till you make it, column edition. πŸ”₯

🫢 get_inflated_columns 🫢

my %inflated_data = $obj->get_inflated_columns;

Arguments: none Return Value: A hash of column, object|value pairs

Returns a hash of all column keys and associated values. Values for any columns set to use inflation will be inflated and returns as objects.

See get_columns to get the uninflated values.

See DBIx::Class::InflateColumn for how to setup inflation.

πŸ’– set_column πŸ’–

$result->set_column($col => $val);

Arguments: $columnname, $value Return Value: $value

Sets a raw column value. If the new value is different from the old one, the column is marked as dirty for when you next call update. That's the whole glow-up. πŸ’…

If you hand it an object or a reference as a value, this method will happily go ahead and try to store it anyway β€” and then a later insert or update will try to stringify/numify it as appropriate. 😬 If you actually want an object to get deflated instead, peep set_inflated_columns, or honestly just use $column_accessor. That's the move. πŸ’…

🧺 set_columns

$result->set_columns({ $col => $val, ... });

Arguments: \%columndata Return Value: $result

Sets a whole bunch of column / raw value pairs in one go. Works exactly like set_column β€” same energy, just batched. ✨

πŸŽ€ set_inflated_columns

$result->set_inflated_columns({ $col => $val, $rel_name => $obj, ... });

Arguments: \%columndata Return Value: $result

Sets more than one column value at once. Any inflated values get deflated, and the raw values get stored. 🫢

Any related values you pass in as Result objects β€” using the relation name as the key β€” get reduced down to the appropriate foreign key values and stored. And if instead of related result objects you pass a hashref of column / value data, it'll create the related object first and then store it. Iconic behavior, honestly.

It'll even accept arrayrefs of data as a value for a has_many in DBIx::Class::Relationship key, and create the related objects if necessary. Not me being overachieving. 😌

⚠️ Heads up bestie: the input hashref might be edited in place, so don't go relying on it being the same after a call to set_inflated_columns. If you need to preserve the hashref, it's sufficient to pass a shallow copy to set_inflated_columns, like this: perl ( { %{ $href } } )

See also set_from_related in DBIx::Class::Relationship::Base. πŸ’–

πŸ¦‹ copy

my $copy = $orig->copy({ change => $to, ... });

Arguments: \%replacementdata Return Value: $result copy

Inserts a brand new row into the database, as a copy of the original object. If you supply a hashref of replacement data, those values take precedence over whatever's in the original. Also β€” and this is the good part β€” any columns that have the column info attribute is_auto_increment => 1 are explicitly removed before the copy, so the database can insert its own autoincremented values into the new object. Slay. πŸ‘‘

Relationships only get followed by the copy procedure if the relationship specifies a true value for its cascade_copy attribute. cascade_copy is set by default on has_many relationships and unset on all the others. That's just how it is, periodt.

πŸ“ store_column

$result->store_column($col => $val);

Arguments: $columnname, $value Return Value: The value sent to storage

Sets a raw value for a column without marking it as changed. This one's used internally by set_column β€” which, lowkey, you should probably be using instead.

This is the lowest level at which data is set on a result object, so extend this method if you wanna catch all data setting methods. It's giving main character energy of the data pipeline. πŸ”₯

🌸 inflate_result

Class->inflate_result($result_source, \%me, \%prefetch?)

Arguments: $result_source, \%columndata, \%prefetcheddata Return Value: $result

Every single DBIx::Class::ResultSet method that retrieves data from the database and turns it into result objects calls this method. All of them. No exceptions. πŸ’€

So extend this method in your Result classes to hook into that process β€” for example, to rebless the result into a different class. 🧚

Reblessing can also be done more easily by setting result_class in your Result class β€” see result_class in DBIx::Class::ResultSource. And different types of results can also be created from a particular DBIx::Class::ResultSet, see result_class in DBIx::Class::ResultSet. Options! We love options. 🌈

πŸ’œ update_or_insert

$result->update_or_insert

Arguments: none Return Value: Result of update or insert operation

updates the object if it's already in the database β€” according to in_storage β€” else it inserts it. Simple as that. ✨

⭐ insert_or_update

$obj->insert_or_update

Alias for update_or_insert. Same thing, different name, both iconic. πŸ’…

πŸŽ€ is_changed

my @changed_col_names = $result->is_changed();
if ($result->is_changed()) { ... }

Arguments: none Return Value: 0|1 or @columnnames

In list context it returns a list of columns with uncommitted changes. In scalar context it returns a true value if there are uncommitted changes. Vibe check on your unsaved edits fr fr. 🫢

πŸ¦‹ is_column_changed

if ($result->is_column_changed('col')) { ... }

Arguments: $columname Return Value: 0|1

Returns a true value if that specific column has uncommitted changes. Single-column vibe check. πŸ“

🌟 result_source

my $resultsource = $result->result_source;

Arguments: $result_source? Return Value: $result_source

Accessor to the DBIx::Class::ResultSource this object was created from. Like a little baby photo but for your resultsource. πŸŽ€

🧚 register_column

$column_info = { .... };
$class->register_column($column_name, $column_info);

Arguments: $columnname, \%columninfo Return Value: not defined

Registers a column on the class. If the column_info has an 'accessor' key, it creates an accessor named after that value if it's defined; if there's no such key, it creates an accessor with the same name as the column. 🌸

The column_info attributes are described in add_columns in DBIx::Class::ResultSource β€” go read that if you want the full tea. β˜•

πŸ”₯ get_from_storage

my $copy = $result->get_from_storage($attrs)

Arguments: \%attrs Return Value: A Result object

Fetches a fresh copy of the Result object from the database and returns it. It throws an exception if a proper WHERE clause identifying the database row can't be constructed (i.e. if the original object doesn't contain its entire primary key). Like, it needs the whole key bestie, no partials. 😭

If you pass the \%attrs argument, it'll first apply those attributes to the resultset used to find the row.

This copy can then be used to compare to an existing result object, to determine if any changes have been made in the database since it was created. Detective mode. πŸ”

If you just wanna update your Result object with the latest changes from the database, use discard_changes instead β€” that's literally its whole thing.

The \%attrs argument should be compatible with ATTRIBUTES in DBIx::Class::ResultSet. 🫢

πŸ’€ discard_changes

$result->discard_changes

Arguments: none or $attrs Return Value: self (updates object in-place)

Re-selects the row from the database, losing any changes that had been made. Gone. Poof. πŸ™ˆ It throws an exception if a proper WHERE clause identifying the database row can't be constructed (i.e. if the original object doesn't contain its entire primary key).

This method can also be used to refresh from storage, retrieving any changes made since the row was last read from storage. Glow-up from the source of truth. ✨

$attrs, if supplied, is expected to be a hashref of attributes suitable for passing as the second argument to:

$resultset->search($cond, $attrs)
πŸ“Œ Note: If you're using DBIx::Class::Storage::DBI::Replicated as your storage, a default of { force_pool => 'master' } is automatically set for you. Prior to DBIx::Class 0.08109 (before 2010) you would have been required to explicitly wrap the entire operation in a transaction to guarantee that up-to-date results are read from the master database. Ancient history, but now you know. πŸ›οΈ

🫢 throw_exception

See throw_exception in DBIx::Class::Schema. That's it, that's the whole entry. πŸ’…

πŸ‘‘ id

my @pk = $result->id;

Arguments: none Returns: A list of primary key values

Returns the primary key(s) for a row. Can't be called as a class method β€” it's an instance thing. Actually implemented in DBIx::Class::PK. ⭐


πŸ’¬ FURTHER QUESTIONS? πŸ’¬

Check the list of additional DBIC resources. There's a whole world of lore out there, go explore bestie. 🌈

This module is free software copyright by the DBIx::Class (DBIC) authors. You can redistribute it and/or modify it under the same terms as the DBIx::Class library. 🫢


And that's the whole page, no cap! πŸŽ‰ Brought to you by perl v5.42.0, dated 2025-01-22, and filed under DBIx::Class::Row(3). Go forth and query responsibly, bestie πŸ’–βœ¨

πŸ“¦ where this page comes from