I have debugged this function today: I can see you concern as this function seems big and we can see some load/save function calls within it.
However, after inspecting the code, load and save in fact are not calling the database but rather feed property in the classes that appears to be a 'shared' model.
--> each time the function is called, it will assign the attribute's data onto an array that is a property of the Config model and this property will prevent further calls to be doing the whole lot of code lines again..
The one line that could harm is in the function \Magento\Eav\Model\Entity\Collection\AbstractCollection::addAttributeToSelect
in this function, the line $attrInstance = $this->_eavConfig->getAttribute($this->getEntity()->getType(), $attribute);
seems to be what will finally load the data for the attribute. However, if your system happens to be using a cache, this should use the cache storage to read the data and that means it should load at the fastest speed you can get.
Long story short, this function is typically a function in Magento that is doing a lot but after all these years of settling Magento as a premium ecommerce platform, it is quite clear Magento team has not fallen in basic traps of calling greedy functions again and again.
After understanding your question, Not sure but, it seems like your InstallSchema not create properly with foreign key constraint and you didn't properly assign your attributes name in your ResourceModel file.
Compare this both file with your code.
InstallSchema.php :
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
/**
* Code standard by : RH
*/
namespace RH\HelloWorld\Setup;
use Magento\Framework\DB\Ddl\Table;
use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use RH\HelloWorld\Setup\EavTablesSetupFactory;
use RH\HelloWorld\Setup\HelloWorldSetup;
class InstallSchema implements InstallSchemaInterface
{
/**
* @var EavTablesSetupFactory
*/
protected $eavTablesSetupFactory;
/**
* Init
*
* @internal param EavTablesSetupFactory $EavTablesSetupFactory
*/
public function __construct(EavTablesSetupFactory $eavTablesSetupFactory)
{
$this->eavTablesSetupFactory = $eavTablesSetupFactory;
}
/**
* {@inheritdoc}
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
{
$setup->startSetup();
$tableName = HelloWorldSetup::ENTITY_TYPE_CODE;
/**
* Create entity Table
*/
$table = $setup->getConnection()
->newTable($setup->getTable($tableName))
->addColumn(
'entity_id',
Table::TYPE_INTEGER,
null,
['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
'Entity ID'
)->setComment('Entity Table');
$table->addColumn(
'entity_type_id',
Table::TYPE_SMALLINT,
null,
[
'unsigned' => true,
'nullable' => false,
'default' => '0',
],
'Entity Type ID'
)->addIndex(
$setup->getIdxName($tableName, ['entity_type_id']),
['entity_type_id']
)->addForeignKey(
$setup->getFkName(
'rh_helloworld_helloworld',
'entity_type_id',
'eav_entity_type',
'entity_type_id'
),
'entity_type_id',
$setup->getTable('eav_entity_type'),
'entity_type_id',
\Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
\Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
);
$table->addColumn(
'attribute_set_id',
Table::TYPE_SMALLINT,
null,
[
'unsigned' => true,
'nullable' => false,
'default' => '0',
],
'Attribute Set ID'
)->addIndex(
$setup->getIdxName($tableName, ['attribute_set_id']),
['attribute_set_id']
)->addForeignKey(
$setup->getFkName(
'rh_helloworld_helloworld',
'attribute_set_id',
'eav_attribute_set',
'attribute_set_id'
),
'attribute_set_id',
$setup->getTable('eav_attribute_set'),
'attribute_set_id',
\Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
\Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
);
// Add more static attributes here...
$table->addColumn(
'created_at',
Table::TYPE_TIMESTAMP,
null,
['nullable' => false, 'default' => Table::TIMESTAMP_INIT],
'Creation Time'
)->addColumn(
'updated_at',
Table::TYPE_TIMESTAMP,
null,
['nullable' => false, 'default' => Table::TIMESTAMP_INIT_UPDATE],
'Update Time'
);
$setup->getConnection()->createTable($table);
/** @var \RH\HelloWorld\Setup\EavTablesSetup $eavTablesSetup */
$eavTablesSetup = $this->eavTablesSetupFactory->create(['setup' => $setup]);
$eavTablesSetup->createEavTables(HelloWorldSetup::ENTITY_TYPE_CODE);
$setup->endSetup();
}
}
HelloWorldSetup.php :
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
/**
* Code standard by : RH
*/
namespace RH\HelloWorld\Setup;
use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface;
use Magento\Eav\Setup\EavSetup;
class HelloWorldSetup extends EavSetup {
/**
* Entity type for Hello World EAV attributes
*/
const ENTITY_TYPE_CODE = 'rh_helloworld_helloworld';
/**
* EAV Entity type for Hello World EAV attributes
*/
const EAV_ENTITY_TYPE_CODE = 'rh_helloworld';
/**
* Retrieve Entity Attributes
*
* @return array
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
protected function getAttributes() {
$attributes = [];
$attributes['main_title'] = [
'group' => 'General',
'type' => 'varchar',
'label' => 'Main Title',
'input' => 'text',
'global' => ScopedAttributeInterface::SCOPE_STORE,
'required' => '1',
'user_defined' => false,
'default' => '',
'unique' => false,
'position' => '10',
'note' => '',
'visible' => '1',
'wysiwyg_enabled' => '0',
];
// Add your more entity attributes here...
return $attributes;
}
/**
* Retrieve default entities
*
* @return array
*/
public function getDefaultEntities() {
$entities = [
self::ENTITY_TYPE_CODE => [
'entity_model' => 'RH\HelloWorld\Model\ResourceModel\HelloWorld',
'attribute_model' => 'RH\HelloWorld\Model\ResourceModel\Eav\Attribute',
'table' => self::ENTITY_TYPE_CODE,
'increment_model' => null,
'additional_attribute_table' => 'rh_helloworld_eav_attribute',
'entity_attribute_collection' => 'RH\HelloWorld\Model\ResourceModel\Attribute\Collection',
'attributes' => $this->getAttributes(),
],
];
return $entities;
}
}
For more, You can take reference from here. It maybe helpful for you.
Reference
Best Answer
Part 1
For the purpose of this demo I'm going to create a module, let's name it
Easylife_News
that contains an entity namedArticle
.The module comes with complete CRUD code for backend, including the section for managing attributes, and some simple frontend listing and view page for each article. It also ads a menu item in the top menu to the listing of articles.
It also contains URL rewrites, RSS feed and breadcrumbs for frontend. This entity will have 4 attributes:
Title, Short Description, Description, Publish Date
in addition to the system ones (created_at
,updated_at
,status
,in_rss
,url_key
).The module should contain the following files.
app/etc/module/Easylife_News.xml
- the declaration module:app/code/local/Easylife/News/etc/config.xml
- the configuration fileapp/code/local/Easylife/News/etc/adminhtml.xml
- the admin acl and menu file.app/code/local/Easylife/News/etc/system.xml
- the system configuration file. It allows you to manage a few settings like SEO for the articles list, breadcrumbs, RSS enable/disable, url prefix and suffixapp/code/local/Easylife/News/sql/easylife_news_setup/install-1.0.0.php
- the install scriptModels
app/code/local/Easylife/News/Model/Observer.php
- add the new menu item on the top menu:app/code/local/Easylife/News/Model/Article.php
- the article main modelapp/code/local/Easylife/News/Model/Resource/Article.php
- the resource model for the articleapp/code/local/Easylife/News/Model/Resource/Article/Collection.php
- the collection modelThe code is too long to fit in one answer. The rest will follow....wait for it.