I'm trying to use the ORM RedBeanPHP (v3.3) in a ZF2 (v2.0.2) application and I'm having trouble with its automatic FUSE model. I can't make it link to my model classes. It's not picking them up automatically and using "regular" beans instead.
I'm using the RjhRedbean module to load up RedBean in ZF2.
My model class is the following, placed in the folder .\module\Check\src\Check\Model\Model.
<?php
namespace Check\Model;
use \RedBean_SimpleModel;
class Model_Check extends RedBean_SimpleModel
{
public $id;
public $type;
...
public function open()
{
}
public function toArray()
{
return array($this->id, $this->type);
}
I confirm it's picked up by the autoloader since $c = new Model_Check(); works.
My controller code trying to load all the Check model objects from the DB is:
<?php
namespace Check\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\View\Model\JsonModel;
use RjhRedbean;
use Check\Model\Model_Check;
class CheckController extends AbstractActionController
{
public function listAction()
{
$rb = $this->getServiceLocator()->get('RjhRedbean');
$checks = $rb->findAll('Check'); // does not link to my Model object
foreach ($checks as $check) {
$ar = $check->toArray(); // does not exist in the objects returned
...
The objects returned are RedBean_OODBBean
What should I put as the bean name in the findAll() method? I tried:
$checks = $rb->findAll('Model_Check');
$checks = $rb->findAll('Check/Model/Check');
$checks = $rb->findAll('Check/Model/Model_Check');
Nothing seems to do the trick. When creating a bean, I get the same problems too...
Thanks.
The reason that this isn't working is that FUSE cannot automatically find the Model for the bean as it would normally do due to problems introduced in using namespaces.
You can work around this problem by using a class map file and defining all Models that you are using in there. Making sure you models are in the global namespace.
More information and examples can be found on my blog: How to use FUSE models in RjhRedbean
I modified RjhRedbean module as followed:
1.Created a class named ModelFormatter
this class does nothing else but return the appropriate namespace related to your models.
the namespace can be set in your config.
2.In the RjhRedbeanServiceFactory class added
RedBean_ModelHelper::setModelFormatter($serviceLocator->get('ModelFormatter'));
Related
I am new to Dependency Injection and currently using Ninject as my DI. I have been playing with a ASP.Net MVC 5 application and have been reading "Pro ASP.NET MVC 5". I have followed the examples in the book on how to set up and use Ninject. Below is the code for my register services:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<ICustomerRepository>().To<CustomerRepository>();
kernel.Bind<ICustomerUserDataRepository>().To<CustomerUserDataRepository>();
}
As for my controller I have below:
public class CustomerController : Controller
{
private ICustomerRepository customerRepository;
public CustomerController(ICustomerRepository customerRepo)
{
this.customerRepository = customerRepo;
}
// GET: Customer
public ActionResult Index(int Id = 0)
{
Customer customer = customerRepository.GetCustomer(Id).First();
return View(customer);
}
}
This works fine as expected in the book. However, I have been playing around with some other code and wanted to further use Ninject to resolve some dependencies. For example, I am working on a custom helper for one of my Razor views. In the my helper code I have the following:
using (IKernel kernel = new StandardKernel())
{
ICustomerUserDataRepository customerUserDataRepo = kernel.Get<ICustomerUserDataRepository>();
When I run this, it complains that there is no binding defined for ICustomerUserDataRepository. I am assuming this is because I am using a new kernel with no defined bindings. I read that you need to load bindings in kernels through modules. So I made the following:
public class MyBindings : NinjectModule
{
public override void Load()
{
Bind<ICustomerUserDataRepository>().To<CustomerUserDataRepository>();
}
}
I then load the module when setting my kernel below:
using (IKernel kernel = new StandardKernel(new MyBindings()))
{
ICustomerUserDataRepository customerUserDataRepo = kernel.Get<ICustomerUserDataRepository>();
This however causes a "Error loading Ninject component ICache" error message when I execute the application. I would appreciate some help on what I am doing wrong and what I am not understanding. I read that multiple defined kernels can cause this error. Am I not suppose to be using a new kernel in my helper method since one is already being used and binded under RegisterServices()? If so, am I suppose to access that existing kernel in my helper method? Or am I on the right track and need a new kernel loading the specific bindings in my module? Thank you.
Am I not suppose to be using a new kernel in my helper method since one is already being used and binded under RegisterServices()?
correct. you only want one kernel or Composition Root per application. I would suggest that instead of trying to access dependencies in a helper method, that you would create a viewmodel in your Controller (that has access to the dependency) and then pass the viewmodel into your helper method.
I'm trying to use the built-in laravel's Ioc container to inject a PageManager class inside a Page model and I'm a little lost.
What I'm trying to achieve is something like that:
class Pages extends Eloquent {
public function __construct(PagesManagerInterface $manager, array $attributes = array())
{
parent::__construct($attributes);
$this->manager = new $manager;
}
public function saveToDisk()
{
$this->manager->writeToFile();
}
But I obtain this error:
ErrorException: Argument 1 passed to Pages::__construct() must be an instance of PagesManagerInterface, none given.
I tried to add this in app/start/global.php:
App::bind('Pages',function(){
return new Pages(new PagesManager);
});
But is seems ignored by the framework, and also i don't know how to insert the $attribute array into this declaration.
I'm a little lost so any help is appreciated!
It's not a good idea to overload a model's constructor because new instances can be spawned behind the scenes through various methods, like Model::find().
When that happens, the dependencies you're asking for in your custom constructor aren't being passed in because the Model class isn't aware of them. So, you get that error message.
See the find() method here: http://laravel.com/api/source-class-Illuminate.Database.Eloquent.Model.html#380-397
See this post by Jason Lewis: http://forums.laravel.io/viewtopic.php?pid=47124#p47124
I think that what you need is:
App::bind('PagesManagerInterface',function(){
return new Pages(new PagesManager);
});
This tells Laravel to inject a new Page object everytime it needs an instance of your PagesManagerInterface wich wasn't passed while creating the model.
In Laravel you can use the IoC Container:
public function saveToDisk(){
$managerObject = app()->make('path\to\class\PagesManagerInterface');
$managerObject->writeToFile();
}
I have 2 different module in project
1)Album
2)User
I want use some classes of User module in 'Album' Module.
Please help me how I can configure it.
Thanks and Regards,
Ashish
Service Classes should be accessible via the ServiceManager. In case Classes are made available there, either as factories or invokables, you should be able to call them from your Controller like this:
$this->getServiceLocator()->get('name-of-your-service');
Otherwise if it's only classes you need to use, you can simply import and use them like
namespace Othermodule;
use My\Module\Class\Name;
class OtherModuleClass {
public function someAction()
{
new Name();
// Or fully qualified inline
new \Third\Module\Class\Name();
}
}
I have succesfully implemented a RESTful Web Service using the .NET 4.0 framework with MVC 4 and the ApiController class.
I have a method, let's say GetMovies ("/api/movies") that returns an IQueryable<Movie>. Serialization is done using DataContractSerializer, of course. The problem is in the name of the returned list, because it is ArrayOfMovie:
<ArrayOfMovie>
<Movie></Movie>
<Movie></Movie>
...
<Movie></Movie>
</ArrayOfMovie>
I cannot create a custom class, let's say Movies, and add a [CollectionDataContract(Name = "movies")] annotation (as suggested at https://stackoverflow.com/a/4593167/801065) because I cannot extend IQueryable without implementing all of its methods. And I most definitely need an IQueryable for OData/jQuery processing.
How can I solve this? Is there an annotation that can help me?
This is the solution I found.
You need to put a group class in the main class you want to serialize.
[DataContract(Name = "movies")]
public class group
{
[DataMember(Name="movies")]
public IQueryable<Movie> Movies;
}
I've added some functionality to some of my instance classes in my symfony project that I want ALL of my instance classes to have. If I didn't have any qualms about editing the core symfony installation, I would just add my methods directly to the sfDoctrineRecord class. But I don't want to do that, of course, because my changes would break on upgrade, plus my changes wouldn't port well to other projects.
If I want to add certain functionality to all my instance classes in symfony, what's the "right" way to do that?
(P.S. When I say "instance class", I mean something like lib/model/doctrine/Customer.class.php.)
Steps:
Create myDoctrineRecord
abstract class myDoctrineRecord extends sfDoctrineRecord
{
public function commonRecordMethod() { }
}
I place this file in lib/record, but you can put it anywhere that the autoloader will see it.
Set Symfony to use this class in the configureDoctrine callback of your ProjectConfiguration:
public function configureDoctrine(Doctrine_Manager $manager)
{
sfConfig::set('doctrine_model_builder_options', array('baseClassName' => 'myDoctrineRecord'));
}
That's it! Isn't Symfony great? :)
I suppose the proper way would probably be to add a Doctrine_Template to the models in question, however you would need to define it as a behavior for every model in your schema.yml
class MyMethodsTemplate extends Doctrine_Template
{
public function customMethod1(){
$model = $this->getInvoker();
//do stuff with model
}
public function customMethod2(){
$model = $this->getInvoker();
//do stuff with model
}
}
And then in your schema.yml:
ModelName:
actAs:
MyMethodTemplate: ~
# the rest of your definition
After you rebuild you should be able to call:
$model = new ModelName();
$model->customMethod1();
$model->customMethod2();
Of course Doctrine templates and listeners are much more powerful than that. You should take a look at the documentation for decent overview