NAME

DBIx::Class::MethodAttributes - DBIC-specific handling of CODE attributes

SYNOPSIS

my @attrlist = attributes::get( \&My::App::Schema::Result::some_method )

DESCRIPTION

This class provides the DBIx::Class inheritance chain with the bits necessary for attribute support on methods.

Historically DBIC has accepted any string as a CODE attribute and made such strings available via the semi-private "_attr_cache" method. This was used for e.g. the long-deprecated DBIx::Class::ResultSetManager, but also has evidence of use on both CPAN and DarkPAN.

Starting mid-2016 DBIC treats any method attribute starting with DBIC_ as an internal boolean decorator for various DBIC-related methods. Unlike the general attribute naming policy, strict whitelisting is imposed on attribute names starting with DBIC_ as described in "VALID_DBIC_CODE_ATTRIBUTE" below.

DBIC-specific method attributes

The following method attributes are currently recognized under the DBIC_* prefix:

DBIC_method_is_indirect_sugar

The presence of this attribute indicates a helper "sugar" method. Overriding such methods in your subclasses will be of limited success at best, as DBIC itself and various plugins are much more likely to invoke alternative direct call paths, bypassing your override entirely. Good examples of this are "create" in DBIx::Class::ResultSet and "connect" in DBIx::Class::Schema.

See also the check "no_indirect_method_overrides" in DBIx::Class::Schema::SanityChecker.

DBIC_method_is_mandatory_resultsource_proxy

DBIC_method_is_bypassable_resultsource_proxy

The presence of one of these attributes on a proxied ResultSource method indicates how DBIC will behave when someone calls e.g.:

$some_result->result_source->add_columns(...)

as opposed to the conventional

SomeResultClass->add_columns(...)

This distinction becomes important when someone declares a sub named after one of the (currently 22) methods proxied from a Result to ResultSource. While there are obviously no problems when these methods are called at compile time, there is a lot of ambiguity whether an override of something like columns_info will be respected by DBIC and various plugins during runtime operations.

It must be noted that there is a reason for this weird situation: during the original design of DBIC the "ResultSourceProxy" system was established in order to allow easy transition from Class::DBI. Unfortunately it was not well abstracted away: it is rather difficult to use a custom ResultSource subclass. The expansion of the DBIC project never addressed this properly in the years since. As a result when one wishes to override a part of the ResultSource functionality, the overwhelming practice is to hook a method in a Result class and "hope for the best".

The subtle changes of various internal call-chains in DBIC v0.0829xx make this silent uncertainty untenable. As a solution any such override will now issue a descriptive warning that it has been bypassed during a $rsrc->overridden_function invocation. A user must determine how each individual override must behave in this situation, and tag it with one of the above two attributes.

Naturally any override marked with ..._bypassable_resultsource_proxy will behave like it did before: it will be silently ignored. This is the attribute you want to set if your code appears to work fine, and you do not wish to receive the warning anymore (though you are strongly encouraged to understand the other option).

However overrides marked with ..._mandatory_resultsource_proxy will always be reinvoked by DBIC itself, so that any call of the form:

$some_result->result_source->columns_info(...)

will be transformed into:

$some_result->result_source->result_class->columns_info(...)

with the rest of the callchain flowing out of that (provided the override did invoke next::method where appropriate)

DBIC_method_is_generated_from_resultsource_metadata

This attribute is applied to all methods dynamically installed after various invocations of ResultSource metadata manipulation methods. Notably this includes add_columns, add_relationship, the proxied relationship attribute and the various relationship helpers, except the M2M helper (given its effects are never reflected as ResultSource metadata).

DBIC_method_is_column_accessor

This attribute is applied to all methods dynamically installed as a result of invoking add_columns.

DBIC_method_is_inflated_column_accessor

This attribute is applied to all methods dynamically installed as a result of invoking inflate_column.

DBIC_method_is_filtered_column_accessor

This attribute is applied to all methods dynamically installed as a result of invoking filter_column.

DBIC_method_is_*column_extra_accessor

For historical reasons any Class::Accessor::Grouped accessor is generated twice as {name} and _{name}_accessor. The second method is marked with DBIC_method_is_*column_extra_accessor correspondingly.

DBIC_method_is_single_relationship_accessor

This attribute is applied to all methods dynamically installed as a result of invoking might_have, has_one or belongs_to (though for belongs_to see ...filter_rel... below.

DBIC_method_is_multi_relationship_accessor

This attribute is applied to the main method dynamically installed as a result of invoking has_many.

DBIC_method_is_multi_relationship_extra_accessor

This attribute is applied to the two extra methods dynamically installed as a result of invoking has_many: $relname_rs and add_to_$relname.

DBIC_method_is_filter_relationship_accessor

This attribute is applied to (legacy) methods dynamically installed as a result of invoking belongs_to with an already-existing identically named column. The method is internally implemented as an inflated_column and is labeled with both atributes at the same time.

DBIC_method_is_filter_relationship_extra_accessor

Same as "DBIC_method_is_*column_extra_accessor".

DBIC_method_is_proxy_to_relationship

This attribute is applied to methods dynamically installed as a result of providing the proxied relationship attribute.

DBIC_method_is_m2m_sugar

DBIC_method_is_m2m_sugar_with_attrs

One of the above attributes is applied to the main method dynamically installed as a result of invoking many_to_many. The _with_atrs suffix serves to indicate whether the user supplied any \%attrs to the many_to_many call. There is deliberately no mechanism to retrieve the actual supplied values: if you really need this functionality you would need to rely on DBIx::Class::IntrospectableM2M.

DBIC_method_is_extra_m2m_sugar

DBIC_method_is_extra_m2m_sugar_with_attrs

One of the above attributes is applied to the extra four methods dynamically installed as a result of invoking many_to_many: $m2m_rs, add_to_$m2m, remove_from_$m2m and set_$m2m.

METHODS

MODIFY_CODE_ATTRIBUTES

See "MODIFY_type_ATTRIBUTES" in attributes.

FETCH_CODE_ATTRIBUTES

See "FETCH_type_ATTRIBUTES" in attributes. Always returns the combination of all attributes: both the free-form strings registered via the legacy system and the DBIC-specific ones.

VALID_DBIC_CODE_ATTRIBUTE

Arguments: $attribute_string
Return Value: ( true| false )

This method is invoked when processing each DBIC-specific attribute (the ones starting with DBIC_). An attribute is considered invalid and an exception is thrown unless this method returns a truthy value.

_attr_cache

Arguments: none
Return Value: purposefully undocumented

The legacy method of retrieving attributes declared on DBIC methods ("FETCH_CODE_ATTRIBUTES" was not defined until mid-2016). This method does not return any DBIC-specific attributes, and is kept for backwards compatibility only.

In order to query the attributes of a particular method use attributes::get() as shown in the "SYNOPSIS".

FURTHER QUESTIONS?

Check the list of additional DBIC resources.

COPYRIGHT AND LICENSE

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.