Replace the column name in the magento collection while loading it - magento

I have a custom module and I am loading a collection like following
$collection = Mage::getModel('module/product')->getCollection()
->addFieldToFilter('sku',$sku);
There is field named as prod_id in the database. Can I get this as entity_id while loading the collection?
If yes. Please help how to do this.

First of all all
addAttributeToFilter() is used to filter EAV collections.
addFieldToFilter() is used to filter Non-EAV collections.
EAV-models are for example product, customer, sales, etc so you can use use addAttributeToFilter() for those entities.
addFieldToFilter() is mapped to `addAttributeToFilter()` for `EAV` entities. So you can just use `addFieldToFiler().`
You can have a look in app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php where the Mapping is done:
public function addFieldToFilter($attribute, $condition = null) {
return $this->addAttributeToFilter($attribute, $condition);
}
If you are using custom module then you can directly use addFieldToFilter() with your column name
Like
$collection = Mage::getModel('module/model')->getCollection()
->addFieldToFilter('column_name',$data);
Let me know if you have any query

Related

sort laravel eloquent by custom (appended) attribute

I have a model with a custom attribute like this
public function getOpenStatusAttribute()
{
//some logic...
//returns '1-order' or '2-pre-order' or '3-closed'
}
Now i want to sort the collection in the eloquent query. I use order by name etc.. those are columns in the table but i want to order it by the custom attribute first, and then by name etc..
is it possible to do this in the query? or do i have to loop the collection and do some resorting ?
ok so the solution is:
->sortBy(['open_status'])->sortBy(['name']);
after the ->get()
hope it can help someone in the future

Adding data to an eloquent collection?

Im getting various data out of my database.
Product::with('users');
I also have toe execute a complex raw query to get back some information. This is returned as an array.
In my method I would like to get products with users and then add on the data from my raw query to this collection, but this data comes back as an array. Something like:
Product::with('users');
Product->extraData = $rawQuery;
How can I add the raw query output to my Product Collection?
By using Eloquent Facade like Product:: you will get an Eloquent Model object as a result or an Eloquent Collection object as a result, including results retrieved via the get method or accessed via a relationship.
Now, if i understand correctly, you need to add a single extraData property to Eloquent Collection model alongside with Collection items? Or you need to add extraData for each Product ?
If you need to add additional property to Eloquent Collection object, maybe it is a good idea to use a Custom Collection. Please read this section: http://laravel.com/docs/5.1/eloquent-collections#custom-collections .
<?php namespace App;
use App\CollectionWithExtraData;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function newCollection(array $models = [])
{
return new CollectionWithExtraData($models);
}
}
And maybe your CollectionWithExtraData can have let's say a
public function setExtraData() {
}
or
public $extraData = array();
If you need extraData for each Product Eloquent Model, just create a new attribute within your Eloquent Model, make it public and set your extra data when needed. Make use of setExtraData() method and $extraData property from above

How do I keep models loosely coupled when querying a many-to-many table in CodeIgniter?

I'm using CodeIgniter and have three tables and a model for each:
User - table of users
Product - table of products
UserProduct - table showing which users have which products (two foreign key columns, and some other columns such as date)
In my code I want to display a list for a particular user showing which products they have. So I have a method in the UserProduct class that does a select on the UserProduct table matching for the userId, and a join bringing in all the data I need about each product.
This works fine, but I am concerned now that I am moving down a path of tight coupling. For example, say I want to find out the URL of a product image. I have a method in the product model to return this, I don't want a duplicate method in the UserProduct model, and I don't want to create a coupling by having the UserProduct model trying to access methods in other models (which I don't think CodeIgniter likes you to do).
This problem seems likely to occur in any model that accesses a DB table that has foreign keys where that model may need data from the parent table and want to manipulate it.
Is there an elegant solution, or do I need to accept that foreign keys necessarily create couplings in models or the need for similar methods across models?
TIA,
Phil.
My personal standard is to create 1 controller + 1 model always.
for example site.com/users will use model_users.php
or
site.com/products will use model_products.php
to slim your code and re-use methods use methods params for example a model method to be re-used could be:
function getUsers($data){
foreach($data as $key=>$value){
$this->db->where($key,$value);
}
$query = $this->db->get('users');
return $query->result();
}
the more you extend this method the more you can re-use, just another example of extending:
function getUsers($data,$order_by = false){
foreach($data as $key=>$value){
$this->db->where($key,$value);
}
if($order_by){
foreach($order_by as $key=>$value){
$this->db->order_by($key,$value);
}
}
$query = $this->db->get('users');
return $query->result();
}
//then you call results with this in your controller
$results = $this->model->getUsers(
$data = array('id'=>'12','country'=>'USA'),
$order_by = array('username'=>'DESC')
);
so now you got also order_by , and so on, you can add joins, limit,offset,like etc.. all in the same or quite the same way , the more accurated you are the more you can re-use the same methods

Magento: Get collection from custom query

We can write a custom query in Magento:
$write = Mage::getSingleton('core/resource')->getConnection('core_write');
$write->query("insert into tablename values ('aaa','bbb','ccc')");
Now how can I get the output of query into a collection as I get from Mage::getModel()->getCollection ?
Create an object that extends one of the base collection objects, and add your query to the load method.

How to select from magento EAV tables when flat catalog product data is on

I have this code for selecting best selling products from Magento:
$productCollection = Mage::getResourceModel('reports/product_collection')
->addOrderedQty($startTime, $currentTime)
->addAttributeToSelect('*')
->setStoreId($storeId)
->addStoreFilter($storeId)
->setOrder('ordered_qty', 'desc')
->setPageSize($this->limit());
}
and it works fine, until I set "use flat catalog product" in backend to yes.
Is there any way to tell magento to not use flat tables, and use EAV instead?
Can any one help me with this.
Create a new model class ('mycatalog/product') that extends the original product class but hard code it to use the EAV resource model and EAV resource collection, and then use that model in your query code.
I'd been running my code from a stand alone php file, as soon as i moved my code into an admin module it stopped using the flat_file and went back to eav.
If you look at: Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection
There's a method:
public function isEnabledFlat()
{
if (Mage::app()->getStore()->isAdmin()) {
return false;
}
if (!isset($this->_flatEnabled[$this->getStoreId()])) {
$this->_flatEnabled[$this->getStoreId()] = $this->getFlatHelper()
->isEnabled($this->getStoreId());
}
return $this->_flatEnabled[$this->getStoreId()];
}
You could modify this to add an extra condition that returns false based on your own criteria.
BTW, The reports collection mentioned in the first post by Blazo is an extension of this collection.
To expand on Alan's answer:
class Namespace_Module_Model_Category extends Mage_Catalog_Model_Category
{
protected function _construct()
{
$this->_init('catalog/category');
}
}
The above removes the check to see if flat was enabled and only inits the standard eav verson of the catalog/category resource.
And then when you wish to load your model ensuring that you get the eav model regardless of wither the flat data is enabled:
$category = Mage::getModel('namespace_module/category')->load($id)
I have use
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
before
Mage::getModel('catalog/product')->getCollection()
And it start fetching data from eav based system.
This is an old post but I thought one important point was not stated.
1. Once you set flat catalog to on you need to run indexer via cron or via admin/shell so that flat catalog tables get populated.
If you do have many products in your search bypassing flat catalog table will slow down your site and each search code will consume lots of resources.
I found that the easiest solution was to turn off the flat tables and then get the SQL query that magento executes using the ->load(true) parameter
e.g.
$collection = Mage::getModel('catalog/category')->getCollection();
$collection
->setStoreId($store->getId())
->addAttributeToSelect('*')
->addAttributeToFilter(array(array('attribute'=>'ig_unifeed_ids', 'like'=>"%:".$this->getId().":%")))
->load(true);
then turn flat tables back on and replace this code with:
$resource = Mage::getSingleton('core/resource');
$readConnection = $resource->getConnection('core_read');
$query = "SELECT `e`.*, `at_ig_unifeed_ids`.`value` AS `ig_unifeed_ids` FROM `catalog_category_entity` AS `e` INNER JOIN `catalog_category_entity_varchar` AS `at_ig_unifeed_ids` ON (`at_ig_unifeed_ids`.`entity_id` = `e`.`entity_id`) AND (`at_ig_unifeed_ids`.`attribute_id` = '139') AND (`at_ig_unifeed_ids`.`store_id` = 0) WHERE (`e`.`entity_type_id` = '3') AND ((at_ig_unifeed_ids.value LIKE '%:".$this->getId().":%'))";
$collection = $readConnection->fetchAll($query);
From this point on you will probably need to change other code like replacing
$category->getId()
with
$category["entity_id"]
I hope this helps a bit...
NOTE: this is a real solution for the IG_Unifeed module magento bug that disregards category filtering when using flat tables.

Resources