Doctrine/Symfony2 get data from tables in relationship - symfony1

I have an table Article that is in relationship with Steps (OneToMany) and Steps with Article ManyToOne.
I get Articles with:
$articles = $this->getDoctrine()
->getRepository("IftodiDesignBundle:Article")
->findAll();
And with foreach I want to show all Articles and Steps:
foreach($articles as $article)
{
$steps = $this->getDoctrine()
->getRepository("IftodiDesignBundle:Steps")
->createQueryBuilder('s')
->where('s.article = \''.$article.'\'')
->getQuery()
->execute();
echo "<b>".$article->getTitle()."</b><br />";
echo $article->getText()."<br />";
}
I don't know how to get data from table Steps usign the table Article and method getSteps() that is generated with Doctrine.
Please help me.
Thanks for the answer.
In table Article I have:
/**
* #ORM\OneToMany(targetEntity="Steps", mappedBy="Steps",cascade={"persist"})
* #ORM\JoinColumn(name="id", referencedColumnName="id_article")
*/
protected $steps;
In table Steps:
/**
* #ORM\ManyToOne(targetEntity="Article", inversedBy="steps")
*
*/
protected $article;
When I do:
$articles = $this->getDoctrine()
->getRepository("IftodiDesignBundle:Article")
->findAll();
If I do:
foreach($articles as $article)
{
$steps = $article->getSteps();
I recieve error:
Notice: Undefined index: Steps in /var/www/design/vendor/doctrine/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php line 1280
If I do that:
$articles = $this->getDoctrine()
->getRepository("IftodiDesignBundle:Article")
->findAll();
foreach($articles as $article)
{
//Queries to DB
$steps = $this->getDoctrine()
->getRepository("IftodiDesignBundle:Steps")
->findBy(array(
"article" => $article->getId()
));
$media = $this->getDoctrine()
->getRepository("IftodiDesignBundle:Media")
->findBy(array(
"step" => $steps[0]->getId()
));
I can obtain data that I need, but here are more interrogation to DB.

Delete #ORM\JoinColumn(name="id", referencedColumnName="id_article") from your annotation - doctrine will map your association into MySQL with sensible defaults.
Once you have deleted, regenerate your SQL: doctrine:schema:update --force
Furthermore if you are looping over your articles to get your steps, you are better off writing a custom method in your repository otherwise each time you call ->getSteps() Doctrine will make an SQL call (imagine looping over 100 articles - you would end up making 101 calls to the database!)
To avoid this you can put a method like so in your repository
public function all()
{
$queryBuilder = $this->getEntityManager()->createQueryBuilder();
$queryBuilder
->select('Article', 'Steps')
->from('IftodiDesignBundle:Article')
->leftJoin('Article.steps', 'Steps')
;
// consider using ->getArrayResult() to use less memory
return $queryBuilder->getQuery()->getResult();
}
I put together a few more best practices in a blog post

Well,
Assuming that you have the following relation in Article model:
/**
* #OneToMany(targetEntity="Step", mappedBy="article")
* #JoinColumn(name="id_article", referencedColumnName="id_article_in_step")
*/
protected $steps;
public function getSteps(){ return $this->steps; }
you will be able to do $article->getSteps();

Related

Querying Relationships in Laravel 5.2

I am having issues trying to query an Eloquent relationship.
I have 2 tables
tbl_deals
id
deal_id
merchant_id
tbl_merchants
id
merchant_id
merchant_url_text
I defined a deal model as
class deal extends Model
{
public function merchant() {
return $this->hasOne('App\merchant', 'merchant_id', 'merchant_id');
}
}
Now, I want to query all deals based where merchant_url_text = a variable in my controller
Here's what I am trying
$deals = deal::with('merchant')->get(); //Retrieving all the deals with merchants
If I return $deals its giving me all deals with merchant relationship.
How do I constraint the deals by saying where merchant_url_text = $variable
I am trying
return $deals->where('merchant_url_text', $merchant_url_text)->get();
but it is giving me an error saying :
"Missing argument 1 for Illuminate\Support\Collection::get(), called in ..."
I tried to lookup the documentation for querying relationships in Laravel Docs. It talks about this example
$user = App\User::find(1);
$user->posts()->where('active', 1)->get();
In this case, its trying to get the first user and finding corresponding posts related to the user.
In my case I want to filter from all deals, the deals that have merchant_url_text = a specific variable in my controller.
Any help on how I can achieve this?
Thanks
Try the following code :
$specific_merchant_url_text = "i don't know";
$deals_with_specific_merchant_url_text = [];
$deals = deal::with('merchant')->get();
foreach($deals as $deal)
if( $deal->merchant->merchant_url_text==$specific_merchant_url_text)
array_push($deals_with_specific_merchant_url_text, $deal);
So you get array of deals with specific merchant url text in deals_with_specific_merchant_url_text.
Another approach using DB object :
$deals = DB::table('deals')
->join('merchants', 'deals.merchant_id', '=', 'merchants.id')
->select('deals.*')
->where('merchants.merchant_url_text', $merchant_url_text)
->get();
Yours with raw :
$deals = deal::selectRaw('tbl_deals.*')
->Join('merchants','deals.merchant_id','=','merchants.merchant_id')
->where('merchants.merchant_url_text', '=', $merchant_url_text) ->get();
Hope this helps.
With takes a callback. This will bring back all deals but only eager load merchants that match.
$deals = Deal::with(['merchant' => function ($query) use ($url_text){
return $query->where('merchant_url_text', $url_text);
}])->get();
Flip-side: if you only want deals with a matching merchant, use where has.
$deals = Deal::whereHas('merchant', function ($query) use ($url_text){
return $query->where('merchant_url_text', $url_text);
})->get();
If you want both, chain them:
$deals = Deal::whereHas('merchant', function ($query) use ($url_text){
return $query->where('merchant_url_text', $url_text);
})->with(['merchant' => function ($query) use ($url_text){
return $query->where('merchant_url_text', $url_text);
}])->get();
I capitalized deal because it's standard. It wasn't capitalized in your example.
You can use query builder join query .
DB::table('tbl_merchants')
->join('tbl_deals', 'tbl_merchants.merchant_id', '=','tbl_deals.merchant_id')
->where('tbl_merchants.merchant_url_text',$merchant_url_text)
->get();

yii CdbCriteria nested join

I have trouble creating a CdbCriteria with nested join. Here's the code in model (sorry it's in Indonesian. Hopefully anyone can understand the query):
public function report() {
$criteria=new CDbCriteria;
$criteria->alias = "p";
$criteria->select = "p.tanggal_transaksi,
MONTH( p.tanggal_transaksi ) AS bulan,
p.kode,
p.kode_supplier,
s.nama,
d.kode_bahan_baku,
b.nama_barang,
d.jumlah_kg,
d.jumlah_cones,
d.harga_satuan,
d.harga_satuan * d.jumlah_cones AS total,
FLOOR(d.harga_satuan * d.jumlah_cones * p.ppn / 100) AS ppn,
(d.harga_satuan * d.jumlah_cones) + FLOOR(d.harga_satuan * d.jumlah_cones * p.ppn / 100) AS total_akhir
";
$criteria->join = "JOIN m_supplier s ON s.kode = p.kode_supplier
RIGHT JOIN t_pembelian_detail d ON d.kode_pembelian = p.kode
JOIN m_bahan_baku b ON b.kode = d.kode_bahan_baku
";
$criteria->together = TRUE;
return new CActiveDataProvider(get_class($this), array(
'criteria'=>$criteria,
));
}
The name of the model is TPembelian and here is the relation:
public function relations()
{
return array(
'supplier' => array(self::BELONGS_TO, 'MSupplier', 'kode_supplier'),
'tPembelianDetails' => array(self::HAS_MANY, 'TPembelianDetail', 'kode_pembelian'),
);
}
In a controller, I wrote these lines of codes to just simply print out each attributes of CActiveDataProvider:
$model = new TPembelian('search');
$dataProvider = $model->report();
foreach ($dataProvider->getData() as $data) {
echo "<pre>".print_r($data->attributes, 1)."</pre>";
}
the problem is, it only prints out the attributes from TPembelian model (which use alias "p"). Why are other attributes (with other alias beside "p") not printed?
I have searched for a while and it appears that CActiveDataProvider not returning one long query, but instead it returns many query with HAS_MANY relation. Someone said to use "together" and set it to TRUE (I wrote it already in the code above) to make it returns one long query, but it's still not working. Can anybody please help me?
Note:
in the first code, m_supplier, t_pembelian_detail, and m_bahan_baku are tables, not models

ZF2 - retrieving bottom row id from table

I am trying to retrieve the latest entered if from the 'order' table within my database.
I'm currently trying to use the following method:
public function getLatestOrderId()
{
$adapter = $this->adapter;
$sql = new Sql($adapter);
$select = $sql->select();
$select->columns(array('id' => 'orderId'));
$select->from('order');
$select->order('orderId DESC');
$select->limit(1);
$statement = $sql->prepareStatementForSqlObject($select);
$statement->execute();
}
I have a feeling that this should be working. I am then accessing this method in the controller like so:
$orderId = $this->getOrderTable()->getLatestOrderId();
I have realised that at present the getLatestOrderId method does not actually return anything e.g. return $statement->execute();. This is because I receive an error saying that the sql result could not be converted to a string.
I'm insure what is going wrong, so any help would be much appreciated.
Thank you.

Grails: Use results of Criteria + projections as a filter on the original table

I have the following table/model:
class Post {
int id;
String comment;
static belongsTo = [category_id:Category];
}
I wish to create a query that can filter out the last Post (highest id) per Category. I want the results in List<Post> form.
In other words (I believe) in SQL the query would look as follows:
SELECT *
FROM
Post AS source
JOIN (
SELECT MAX(id) AS id, category_id
FROM Post
GROUP BY category_id
) AS filter
ON source.id = filter.id;
If I understand correctly, the first step is to use a HibernateCriteriaBuilder:
def c = Post.createCriteria();
def results = c.list {
projections {
groupProperty("category_id", "myid")
max("id", "version")
}
}
So my question is a two part:
Am I on the right track?
How can I use the results object to obtain a List<Post> array?
(Something like: def latest = Post.FindAllByXXX(result); )
Yes, you are on the right track. I would also add the id property for the Post to my projections:
projections {
property('id')
}
and then collect all Posts using the id to get a list of posts, something like:
def latestPosts = results?.collect{Post.read(it[0])}

Run view query in Symfony/propel

I've an existing project in Symfony 1.4/Propel 1.4
For database optimization purpose, I created a view of few tables. The function/ view query are as follow:
create function getPlayer() returns INTEGER DETERMINISTIC NO SQL return #getPlayer;
create view getPlay as
SELECT
CASE WHEN play.hiderid = getPlayer() THEN play.seekerid ELSE play.hiderid END AS opponent, play . *
FROM odd_play play, odd_match mat
WHERE (seekerid = getPlayer() OR hiderid = getPlayer())
AND play.id = mat.latestplay;
After creating above view, I can write following simple SQL query to get required data effectively.
select play.*
from (select #getPlayer:=1 p) p, getPlay play;
Now the problem is that, how to write this query in Symfony/Propel 1.4. Can someone please suggest how to write that query in propel 1.4?
Edit after J0K comments
I'm trying following
class GetplayPeer extends BaseGetplayPeer {
static public function getOpponents($player){
$con = Propel::getConnection();
$sql = "select play.* from (select #getPlayer:=:player p) ply, getPlay play;";
$stmt = $con->prepare($sql);
$stmt->bindParam(":player",&$player,PDO::PARAM_INT);
$rs = $stmt->execute();
//$opponents = GetplayPeer::populateObjects($rs);
echo "opponents=<pre>";print_r($rs);exit;
}
} // GetplayPeer
I'm getting 1 as output, which is not expected output.

Resources