I'm attempting to port a custom plugin that was originally written for Craft 2. It has a fair bit of logic, controllers, services, records, models etc. The records and models which I admittedly don't have much experience with are the main area which I'm not fully understanding, but taking the challenge as a learning experience!

After porting the services classes to Craft 3 with namespaces and registering them in the plugin, I've hit the first major block.

The existing Craft 2 service logic seems to call methods that work in Craft 2 but don't seem to exist in Craft 3. Here's the example in Craft 2:

  • MyPlugin_DataRecord::model()
  • MyPlugin_DataModel::populateModel()
  • MyPlugin_DataModel::populateModels()

Example in a service class, which is then used in other places.

protected function getModel()
    return MyPlugin_DataRecord::model();

protected function newModel()
    return new MyPlugin_DataModel();

protected function populateModel($record)
    return MyPlugin_DataModel::populateModel($record);

protected function populateModels($records)
    return MyPlugin_DataModel::populateModels($records, 'id');

These appear to be Craft 2 methods but do not seem to exist at all in Craft 3. Any pointers on how this should be replicated on Craft 3, given it doesn't look like there is any equivalent method in Craft 3 and it could be more of a case of refactor here.

1 Answer 1


I can answer my own question with some information I've found to help anyone else for Craft 2 related porting.

The populateModel() and populateModels() methods used to exist on the BaseModel class in Craft 2:


They were however removed in Craft 3 as discovered and don't have a replacement, this was confirmed from this GitHub issue and conversation:


So in Craft 3, without these methods, you'd essentially have to write a loop each time, which when dealing with multiple models could start to feel like duplicating code. However, reading the conversation around this subject, Ben Croker (putsyourlightson) ended up implementing their own BaseModel class which any required models extend from, so these methods can be used across any model that's being extended from the BaseModel class, which would reimplement the functionality.

Using one of the plugins from putsyourlightson as an example. A BaseModel class is created and then all other models extend from this BaseModel:


The remaining model() method, is actually from an ActiveRecord in Craft 2 and this doesn't exist either in Craft 3, from a Yii2 perspective, ::instance() should provide the same behaviour, providing a static class instance, in Craft 2 it provided a static model of the record.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.