RedBean (ORM) Get Bean with his relations like other Bean - redbean

I'm storing a product Bean, by this way:
$product = R::dispense( 'product' );
$product->name = $_POST['name'];
$product->description = $_POST['description'];
$product->price = $_POST['price'];
$product->category = $_POST['category'];
R::store( $product );
How can I indicate that the category's attribute is an id reference (or
FK) to the category Bean? I want get the category Bean like this way:
$products = R::find( 'product' );
foreach( $products as $product )
$productCategory = $product->category->name;

The way I would do it is this IF you don't have the database table already configured:
$product = R::dispense( 'product' );
$product->name = $_POST['name'];
$product->description = $_POST['description'];
$product->price = $_POST['price'];
$product->category = R::load('category',$_POST['category']);
R::store( $product );
BUT I believe if your database has a foreign index assigned for category and it points to the category table, then you can do what you did above. So on your product table, have a column category_id and make it a foreign index to category.id and it should work. I can test it later and give you a more definitive answer, but this is just going off of what I know offhand.

Related

How to use WHERE for foreign key of a JOINed table in Doctrine?

I have a structure of three tables/entities: User (table users; columns id and name), Room (table roome; columns id and number), and RoomUser (user_room; columns id, user_id, room_id).
Now I want to retrieve all Rooms for a User with a given id. How to do this without to join Rooms?
$userId = 123;
// ...
$queryBuilder = $this->entityManager->createQueryBuilder();
$query = $queryBuilder->select('r')
->from(Room::class, 'r')
->join('r.RoomUsers', 'ru')
->where('ru.room_id = :userId') // room_id? ru.Room.id?
->setParameter('userId', $userId)
->getQuery();
$rooms = $query->getResult(Query::HYDRATE_OBJECT);
So in SQL it would be something like
SELECT *
FROM rooms
JOIN room_users ON room_users.room_id = rooms.id
WHERE user_id = 123;
How to implement this simple request with the QueryBuilder?
You can use MEMBER OF (docs) for that:
$query = $queryBuilder->select('r')
->from(Room::class, 'r')
->where(':user_id MEMBER OF r.users')
->setParameter('user_id', $userId)

How to get the last generated value for a custom PRIMARY KEY column in ZF2?

With Zend\Db\Adapter\Driver\ResultInterface#getGeneratedValue() Zend\Db provides a simple way to get the ID of the last INSERTed entry, e.g.:
$action = new Insert('my_table');
$action->values($data);
$sql = new Sql($this->dbAdapter);
$statement = $sql->prepareStatementForSqlObject($action);
$result = $statement->execute();
$newId = $result->getGeneratedValue();
But it seems only to work, if the PRIMARY KEY column calls "id". How to retrieve the generatedValue for a PRIMARY KEY defined on another column?
Preferably use Zend\Db\TableGateway\TableGateway offering the method getLastInsertValue().
use Zend\Db\TableGateway\TableGateway;
$myTable = new TableGateway('my_table', $this->dbAdapter);
$action = new Insert('my_table');
$action->values($data);
$myTable->insertWith($action);
$newId = $myTable->getLastInsertValue();
$this->dbAdapter->getDriver()->getLastGeneratedValue();

Cannot do Inner join in CDbCriteria

This is mysqli query
SELECT DISTINCT t.company_id,t.image,t.text,t.date, t.title AS c_title
FROM news t
INNER JOIN companies c ON c.company_id=t.company_id ORDER BY t.date DESC
LIMIT 20" or die ("ERROR ". mysqli_error($link));
I want to write in CDbCriteria
$Criteria = new CDbCriteria();
$Criteria->join = 'INNER JOIN companies c ON t.company_id=c.company_id';
if ($place>0){
$Criteria->condition = "t.company_id = :place";
$Criteria->params = array(':place'=>$place);
}
$Criteria->order = "t.date DESC";
$Criteria->limit = 20;
$Criteria->select='t.company_id,t.image,t.text,t.date,c.title AS c_title';
$dataProvider = new CActiveDataProvider('News',
array(
'criteria'=>$Criteria,
'pagination'=>false
)
);
Error Property "News.c_title" is not defined
The property c_title is not defined in your News model (fields from your news table will be available as properties automatically, but c_title is an alias of title and not a field of of your table).
Put this in your News model:
public $c_title;

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

How to create foreign key relationships with the Entity Framework?

I want to create a new row in my database on a table that has a couple of foreign key relationships and I haven't been able to get a handle on what order and what calls need to be made. This is what I have so far:
db.Models.Order order = DB.Models.Order.CreateOrder( apple );
order.CustomerReference.Attach( ( from c in db.Customer where c.Id == custId select c ).First() );
db.SaveChanges();
The code is failing on the second line there, saying:
Attach is not a valid operation when
the source object associated with this
related end is in an added, deleted,
or detached state. Objects loaded
using the NoTracking merge option are
always detached.
Any ideas?
(Thanks John for the grammar fixes)
So I figured it out. This is what you have to do:
db.Models.Order order = DB.Models.Order.CreateOrder( apple );
order.Customer = (from c in db.Customer where c.Id == custId select c).First();
db.SaveChanges();
I hope that helps people.
Why not use entity references? Your method will cause an extra SELECT statement.
A much nicer way is to use the CustomerReference class and an EntityKey.
order.CustomerReference = new System.Data.Objects.DataClasses.EntityReference<Customers>();
order.CustomerReference.EntityKey = new EntityKey("ModelsEntities.Customers", "Id", custId);
For update here is some sample code:
using (var ctx = new DataModelEntities())
{
var result = (from p in ctx.UserRole.Where(o => o.UserRoleId == userRole.UserRoleId)
select p).First();
result.RolesReference.EntityKey = new EntityKey("DataModelEntities.Roles",
"RoleId", userRole.RoleId);
result.UserRoleDescription = userRole.UserRoleDescription;
ctx.SaveChanges();
}

Resources