How can we create new product custom attribute of type boolean(yes/no) using db_schema.xml
(of custom extension) as InstallData
or InstallSchema
file is not being used in Magento 2.3.0 ?
-
Have you try anything?– Dhiren VasoyaDec 25, 2018 at 13:25
-
OK, I agree what Jisse told, anyway I think the right approach is that custom attributes are more used for situation where you also need some GUI for the attributes (like products) ... and extended attribute for somethig more complex data (quote, order).– emastyleFeb 28, 2019 at 16:49
3 Answers
I think the goal is not to add EAV attributes in a scripted way anyway. For sure, the Declarative Schemas are not meant to add product attributes. Instead, consider using Extension Attributes instead (https://devdocs.magento.com/guides/v2.3/extension-dev-guide/attributes.html): Add a file extension_attributes.xml
that defines your attribute. Next, create your own separate table using db_schema.xml
. And then use Plugins (aka Interceptors) to mimic the old behaviour of JOINs by adding your own data to models and collections with methods like afterGetById
or before saving the data with beforeSave
. It's a lot of work, but allows for decoupling of your code.
Use a data patch: Develop data and schema patches
There you can use Magento\Eav\Setup\EavSetup::addAttribute to create your custom product attributes.
For Example:
<?php
namespace Test\Module\Setup\Patch\Data;
use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Catalog\Model\Product;
use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface;
use Magento\Catalog\Model\Product\Attribute\Source\Boolean as SourceBoolean;
use Magento\Catalog\Model\Product\Attribute\Backend\Boolean as BackendBoolean;
class CreateProductAttributes implements DataPatchInterface
{
/**
* @var EavSetupFactory
*/
protected $eavSetupFactory;
/**
* @var ModuleDataSetupInterface
*/
protected $moduleDataSetup;
/**
* CreateIsMagicConfigurableProductAttribute constructor.
* @param EavSetupFactory $eavSetupFactory
* @param ModuleDataSetupInterface $moduleDataSetup
*/
public function __construct(EavSetupFactory $eavSetupFactory, ModuleDataSetupInterface $moduleDataSetup)
{
$this->eavSetupFactory = $eavSetupFactory;
$this->moduleDataSetup = $moduleDataSetup;
}
/**
* @inheritdoc
*/
public static function getDependencies()
{
return [];
}
/**
* @inheritdoc
*/
public function getAliases()
{
return [];
}
/**
* @inheritdoc
*/
public function apply()
{
$eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]);
$eavSetup->addAttribute(
Product::ENTITY,
'custom_attribute_flag',
[
'type' => 'int',
'frontend' => '',
'label' => 'Custom Attribute Flag',
'input' => 'boolean',
'backend' => BackendBoolean::class,
'source' => SourceBoolean::class,
'global' => ScopedAttributeInterface::SCOPE_GLOBAL,
'visible' => false,
'required' => false,
'user_defined' => false,
'default' => '',
'searchable' => false,
'filterable' => false,
'comparable' => false,
'visible_on_front' => false,
'unique' => false,
'apply_to' => ''
]
);
}
}
<?php
declare(strict_types=1);
namespace Vendor\Module\Setup\Patch\Data;
use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface;
use Magento\Catalog\Model\Product;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Catalog\Model\Product\Attribute\Source\Boolean as SourceBoolean;
use Magento\Catalog\Model\Product\Attribute\Backend\Boolean as BackendBoolean;
/**
* Create the attribute for products
*
* Class AddAttribute
*/
class AddAttribute implements DataPatchInterface
{
/**
* ModuleDataSetupInterface
*
* @var ModuleDataSetupInterface
*/
private ModuleDataSetupInterface $moduleDataSetup;
/**
* EavSetupFactory
*
* @var EavSetupFactory
*/
private EavSetupFactory $eavSetupFactory;
/**
* @param ModuleDataSetupInterface $moduleDataSetup
* @param EavSetupFactory $eavSetupFactory
*/
public function __construct(
ModuleDataSetupInterface $moduleDataSetup,
EavSetupFactory $eavSetupFactory
) {
$this->moduleDataSetup = $moduleDataSetup;
$this->eavSetupFactory = $eavSetupFactory;
}
/**
* {@inheritdoc}
*/
public function apply()
{
$eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]);
$eavSetup->addAttribute(Product::ENTITY, 'is_recycable', [
'type' => 'int',
'backend' => BackendBoolean::class,
'frontend' => '',
'label' => 'Enable Recyclable',
'input' => 'boolean',
'class' => '',
'source' => SourceBoolean::class,
'global' => ScopedAttributeInterface::SCOPE_GLOBAL,
'visible' => true,
'required' => false,
'user_defined' => false,
'default' => '',
'searchable' => false,
'filterable' => false,
'comparable' => false,
'visible_on_front' => false,
'used_in_product_listing' => true,
'unique' => false,
'apply_to' => '',
]);
}
/**
* {@inheritdoc}
*/
public static function getDependencies(): array
{
return [];
}
/**
* {@inheritdoc}
*/
public function getAliases(): array
{
return [];
}
}