MongoDB & MySQL relationships in jenssegers/laravel-mongodb - mongodb

Let's begin with some plain code. I have two following models.
First is using MySQL:
class Phrase extends \Eloquent {
public function positions()
{
return $this->hasMany('Position');
}
public function getIdAttribute($id)
{
return (int) $id;
}
}
and second is using MongoDB:
use Jenssegers\Mongodb\Model as Eloquent;
class Position extends Eloquent {
protected $collection = 'positions';
protected $connection = 'mongodb';
public function phrase()
{
return $this->belongsTo('Phrase');
}
}
In my controller I want to get phrase positions:
Phrase::find(1)->positions
which is generating query
positions.find({"positions.phrase_id":1}, [])
instead of
positions.find({"phrase_id":1}, [])
How I can fix it? The problem is inside HasMany method (http://laravel.com/api/source-class-Illuminate.Database.Eloquent.Model.html#_hasMany).

I managed to get the functionality by creating my own function inside the model
class Phrase extends \Eloquent {
public function positions()
{
return Position::where('phrase_id', '=', (int) $this->id)->get();
return $this->hasMany('Position');
}
}
$positions = Phrase::find(1)->positions();
Anyway, this solution is not a great replacement, because it's breaking convention. Third programmers may not know how to use this relationship.

use this trait in both models and u can use basic relationships
use Jenssegers\Mongodb\Eloquent\HybridRelations;
class User extends Model
{
protected $connection = "mysql" ;
use HybridRelations ;
}
class Orders extends Model
{
protected $connection = "mongo" ;
use HybridRelations ;
}

Related

Change name and value of attribute `_class` with Spring Data Couchbase

I changed the way that Spring Data Couchbase writes its _class attribute following this answer. Now, if I save an object of class com.package.entity.User, my document looks like:
{
...
"_type": "user"
}
My point is, when I use query methods like public Long countByAdminIsTrue(), the request generated by Spring is the following:
SELECT COUNT(*) FROM `myBucket` WHERE (`admin` = TRUE) AND `_type` = "com.package.entity.User"
Instead of the result I expect:
SELECT COUNT(*) FROM `myBucket` WHERE (`admin` = TRUE) AND `_type` = "user"
Here is my CouchbaseTypeMapper doint this work:
public class CustomCouchbaseTypeMapper extends DefaultTypeMapper<CouchbaseDocument> implements CouchbaseTypeMapper {
public CustomCouchbaseTypeMapper() {
super(new CustomCouchbaseDocumentTypeAliasAccessor());
}
#Override
public String getTypeKey() {
return "_type";
}
public static final class CustomCouchbaseDocumentTypeAliasAccessor implements TypeAliasAccessor<CouchbaseDocument> {
#Override
public Object readAliasFrom(CouchbaseDocument source) {
return source.get("_type");
}
#Override
public void writeTypeTo(CouchbaseDocument sink, Object alias) {
String typeName = StringUtils.typeNameFromFullClassName((String) alias);
sink.put("_type", typeName);
}
}
}
I already tried to define a ConfigurableTypeInformationMapper in the constructor with my entities, it doesn't help.
How can I make Spring Data to use my custom type name and value when it generates a query based on a query method?

Laravel 5.1 - Cannot access relationship via ORM

I have two model classes as defined as below:
class Event extends Model
{
use SoftDeletes;
protected $dates = ['deleted_at'];
public function user()
{
return $this->belongsTo('App\User');
}
public function transfers()
{
return $this->hasMany('App\Transfer');
}
}
class Transfers extends Model
{
use SoftDeletes;
/**
* The attributes that should be mutated to dates.
*
* #var array
*/
protected $dates = ['deleted_at'];
public function event()
{
return $this->belongsTo('App\Event');
}
}
I am trying access Transfers from an Event object using following code.
public function filter()
{
$id = request()->input('id');
$event = \App\Event::where([['id', '=', $id],
['deleted_at', '=', NULL],
['user_id', '=', auth()->user()->id]])->first();
echo $event->transfers->count();
}
However, it resulted in an exception as follows
Fatal error: Class 'App\Transfer' not found in
D:\work\HC\hcserver\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php
on line 876
Please advice on how to get rid of this exception
Thanks in advance.

Is there a way to use MongoDB without ORM in Laravel 5?

Basically, I see Eloquent (for that matter, any ORM) as overhead, as MongoDB itself deals with document objects.
I am looking to use native PHP MongoDB code with application wide database connection object, for a greater performance.
Any library or a simple way to achieve this?
I have read a few things and used PHP MongoDB driver with custom "Model" code, with base class like below:
AppModel.php
<?php
namespace App;
use MongoClient;
use MongoId;
use Log;
class AppModel {
public $collection;
public function __construct() {
$mongo = new MongoClient();
$model_name = (new \ReflectionClass($this))->getShortName();
$collection_name = str_plural(strtolower($model_name));
$this->collection = $mongo->selectCollection('proj_zabbit', $collection_name);
}
public function findById($id) {
return $this->collection->findOne(array(
'_id' => new MongoId($id)
));
}
// more wrapper functions ..
}
Extended model class:
<?php
namespace App;
class Message extends AppModel {
}
In Controller:
<?php namespace App\Http\Controllers;
use App\Message;
class MessagesController extends Controller {
public function __construct()
{
$this->Message = new Message;
}
public function get()
{
$id = Input::get('id');
$message = $this->Message->findById($id);
return $message;
}
}

Like Query not working in RepoClass

I am having following query.i am not getting output Please help how to retrieve data according to search key word Symfony&MongoDB.
class UsersRepository extends DocumentRepository {
public function getUserByFirstLetter($letter) {
$allusers = $this->createQueryBuilder()
->field('name')->equals(new \MongoRegex('/.*'.$letter.'.*/'))
->getQuery()
->execute();
}
}
I want to get result using LIKE operator.
Thanks
Advance
You have return your result:
class UsersRepository extends DocumentRepository {
public function getUserByFirstLetter($letter) {
return $this->createQueryBuilder()
->field('name')->equals(new \MongoRegex('/.*'.$letter.'.*/'))
->getQuery()
->execute();
}
}

Referencing variable set by application in models (a good idea?)

i am using zend framework 1.10 with doctrine 2. i wonder if in my (doctrine) model class, isit a good idea to reference a variable set by my application (bootstrap.php, variable stored in Zend_Registry, i think its something like a global variable)
what i want to access is the doctrine entityManager. also i want the id of the logged in user
I am building a project with similar setup (ZF 1.10 + Doctrine2) and I've used dependency injection to deal with this situation, much like takeshin said. Here goes full project repository URL: https://bitbucket.org/phpfour/zf-doctrine2. Below are some code excerpts.
Here's my controller:
<?php
require_once APPLICATION_PATH . "/models/PostManager.php";
class IndexController extends Zend_Controller_Action
{
private $_em;
public function init()
{
$this->_em = $this->getInvokeArg('bootstrap')->getResource('doctrine');
}
public function indexAction()
{
$pm = new PostManager($this->_em);
$this->view->posts = $pm->getPublicPosts();
}
My entity manager (or service class):
<?php
class PostManager
{
protected $_em;
public function __construct(Doctrine\ORM\EntityManager $em)
{
$this->_em = $em;
}
public function getPublicPosts()
{
$query = $this->_em->createQuery('SELECT p FROM Entities\Post p WHERE p.visible = true');
$posts = $query->getResult();
return $posts;
}
Hope this helps!
you should simply use Zend_Auth for the logged-in-userId problem, then could do something like the following in your model
class Model extends BaseModel
{
public function something()
{
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
$loggedInUserId = $auth->getIdentity()->id;
}
}
}
There is nothing wrong with this approach (unless you are referring to singletons). Use dependency injection where possible.
However I'd create a service (or two) for this.
class Modulename_Services_Servicename
{
public function getCurrentUser() { ... }
public function getCurrentUserModel() { ... }
public function isLogged() { ... }
public function authenticate() { ... }
public function getSomeData()
{
$user = $this->getCurrentUser()
$model = new YourModel($user);
$query = ....;
$result = $query->execute();
return $result;
}
public function getSomeMoreData($usermodel) { ... }
}