I have a simple relation model in my project, I have requests and comments and created admins classes for both entities. They works just fine as separate admins, and all relations works fine on a public part of the project, but I can't set up comments as a child admin class for requests.
here is what I have in services.yaml
admin.maintenanceRequest:
class: App\Admin\MaintenanceRequestAdmin
arguments: [~, App\Entity\MaintenanceRequest ,~]
tags:
- {name: sonata.admin, manager_type: orm, label: Maintenance }
public: true
calls:
- [ addChild, ['#App\Admin\MaintenanceCommentAdmin', 'maintenance_request_id']]
I also defined $parentAssociationMapping in my child admin class:
protected $parentAssociationMapping = 'maintenance_request_id';
But it leads to this error:
Cannot autowire service "App\Admin\MaintenanceCommentAdmin": argument
"$code" of method
"Sonata\AdminBundle\Admin\AbstractAdmin::__construct()" has no
type-hint, you should configure its value explicitly.
I tried to find solution on my own for quite a while, but seems like no one have problem with that. Hope someone can help me, Im really new to sonata and coding in general, any help would be greatly appreciated. I'll provide any additional info if it's required.
I just found a solution: change your
- [ addChild, ['#App\Admin\MaintenanceCommentAdmin', 'maintenance_request_id']]
with
- [ addChild, ['#admin.maintenanceComment', 'maintenance_request_id']]
Related
I'm looking for a solution regarding following issue: I'm working on a wagtail app which has the following page models
CharacteristicsPage: characteristics of a technology
ModulePage: combination of technologies
For those page models I need a many-to-many relationship because one technology can be included into many modules and one module consists of many technologies.
On the Characteristics page I want to add the related modules with a PageChooserPanel and on the Module page I want to add the related characteristics.
I already found a possible solution on this issue in the following post, but it throws me an error and I can't figure out what's the problem.
Wagtail many-to-many links between different Page models
So maybe can anyone help me with fixing this issue? Am I on the wrong track? Is there a better way of implementing what I want to do? I apprechiate your help.
This is my code:
class ModulePageCharacteristicsPageRelation(models.Model):
module = ParentalKey('library.Modules', on_delete=models.CASCADE, related_name='characteristics'),
characteristic = ParentalKey('library.Characteristics', on_delete=models.CASCADE, related_name='modules')
class Meta:
unique_together = ('module', 'characteristic')
class Modules(Page):
content_panels = Page.content_panels + [
InlinePanel('characteristics', label='Related Characteristic', panels=[PageChooserPanel('characteristic')]),
]
class Characteristics(Page):
content_panels = Page.content_panels + [
InlinePanel('modules', label='Related Modules', panels=[PageChooserPanel('module')])
]
The error message, when I run makemigrations is:
AttributeError: 'ReverseOneToOneDescriptor' object has no attribute 'rel'
In SonataAdmin, the documentation lists three ways of puting custom items in the menu: by configuration, by menu providers, and by events.
Using configuration (or providers) means specifying groups by hand in config, like this:
sonata_admin:
dashboard:
groups:
news:
label: ~
label_catalogue: ~
items:
- sonata.news.admin.post
- route: blog_home
label: Blog
- route: blog_article
route_params: { articleId: 3 }
label: Article
(https://sonata-project.org/bundles/admin/master/doc/cookbook/recipe_knp_menu.html)
But as soon as you declare a non-empty groups array in the config, it overrides the auto generated groups, guessed from the Admin Service Pool.
Is there a way to add groups by hand in the config file, while keeping the groups defined by Admin Services?
Thank you everyone for your time.
The answer is no.
The only option is to use the item_adds entry inside of a group. But that doesn't solve the initial problem.
My advise: do not use auto generated groups. Instead, define them by hand in the config, with some nice built name like sonata.admin.groups.news and them refer to them in the service declaration:
tags:
- { name: sonata.admin, manager_type: orm, group: sonata.admin.groups.news, label: "News" }
What options are there there for resolving nested resources in ngResource responses?
There have been some related questions about resolving endpoints for nested resource in ngResource, but this question is about when a REST response contains a second resource nested in the collection that is being queried, especially 1-to-1 mappings where you wouldn't have e.g. pets/<id>/owner as its own resource.
Say there are two resources, Pets and Owners:
GET /pets:
[{
name: 'spark',
type: 'dog',
owner: '/owners/3/' # alternatively just '3' or the full object.
}]
As a developer, I sometimes want to query the Owner resource as a whole, sometimes I want to query the Pet resource and then I automatically want to resolve the owner attribute into a resource instance.
This is my current solution:
.factory('Pet', function ($resource, Owner) {
var Pet = $resource('/pets/:id', {id: '#id'});
Pet.prototype.getOwner = function () {
return new Owner(this.owner); // or Owner.get({id: this.owner})
}
return Pet;
})
Problems here are many. There's integrity – for one. This implementation, I believe, allows for multiple instances of the same resource. Then there's practicality. You also have additional attributes to keep track of (owner and getOwner(), instead of just owner; possibly setOwner if you want to be able to save the model).
An alternative solution could be built on transformResponse, but it would feel like a hack to include that in every resource that has a nested mapping.
I believe this is the exact reason why Martin Gontovnikas created Restangular. He didn't like having to deal with nested $resources in the main angular framework. I think his Restangular solution would fit nicely into your needs. His code is on GitHub here and he's got a nice intro video on youtube here.
Check it out. I think you'll find it does exactly what you want it to do.
Update: I ended up working on this for a bit and have started a new angular module, available on GitHub. The answer below is about the Gist I wrote originally.
There doesn't seem to be anything around there like what I have been looking for. I have started an implementation of a solution that only supports get and getList (query) operations. The remaining methods should be trivial to add since I've pretty much kept with the layout of the ngResource module. The Gist for my implementation is below.
https://gist.github.com/lyschoening/7102262
Resources can be embedded in JSON either as full objects that simply get wrapped in the correct Resource model, or as URIs, which get resolved automatically. In addition to embedded resources, the module also supports typical nested resources, either as true parent-child collections (where the resource is only accessible after selecting the parent) or as cross-referenced collection.
Yard = Resource('/yard') # resource model
Yard.$nested('trees') # embedded item or list of items
Chair = Resource('/chair')
Yard.$nested('/chair') # sub-collection without its own model
# (for many-to-many)
Tree = Resource('/tree')
# child-collection with its own model
TreeHouse = Tree.$childResource('/treehouse')
yard = Yard.get(1)
# GET /yard/1
# {
# "uri": "/yard/1",
# "trees": [
# "/tree/15", -- reference, looked-up automatically with GET
# {"uri": "/tree/16", "name": "Apple tree"}
# -- full object, resolved to Tree instance
# ]
# }
# GET /tree/16
# {"uri": "/tree/15", "name": "Pine tree"}
yard.chair.getList()
# GET /yard/1/chair
# [{"uri": "/chair/1", ...}, ..]
# -- model inferred from URI
yard.trees[0].treehouse.getList()
# GET /tree/15/treehouse
# [{"uri": "/tree/15/treehouse/1", ...}, ..]
# -- automatically resolved to TreeHouse instance
I am trying to set up cakephp to work with the very nice javascriptMVC (http://forum.javascriptmvc.com). JavaScriptMVC requires the JSON-Output in the following format:
[{
'id': 1,
'name' : 'Justin Meyer',
'birthday': '1982-10-20'
},
{
'id': 2,
'name' : 'Brian Moschel',
'birthday': '1983-11-10'
}]
Cake would generate a deeper nested array with a prepended Class Name. I found attempts to solve the problem but theyre not for cakephp 2.x. I know that I can simply generate a new array and json_encode() it via php, but it would be nicer to include a function like this https://gist.github.com/1874366 and another one to deflatten it.
Where would be the best place to put such functions? The AppController doesnt seem to work. Should i put it in beforeRender () or beforeFilter() of the controller? Or does someone maybe even know of an existing solution/plugin for this? This would be the best for me in my current Situation, as Im pretty much pressed for time.
Ok, I'm not 100% sure I understand what you are trying to do so here's a word to the wise just in case: Cake and JMVC are both comprehensive MVC frameworks. if you are attempting to combine them as a single cohesive platform to build your application, I strongly suggest you review your approach / platform / etc.
Also -- I'm not an expert by any means in jmvc, so I'm just going to pretend that processing the response from Cake in jmvc is completely out of the question, for some odd reason. For the record, think of Cake's responses like this:
{ "Model" :
[{
'id': 1,
'name' : 'Justin Meyer',
'birthday': '1982-10-20'
},
{
'id': 2,
'name' : 'Brian Moschel',
'birthday': '1983-11-10'
}]
}
Cake has had comprehensive REST service support, since at least Cake 1.2. The lib you are interested in is HttpSocket. As for json encoding and serving response, Request Handling covers, among other things, responding to all manners of requests, content types, decoding and encoding json, etc. Finally, the built-in Set utility will almost certainly cover whatever array manipulation you need in a line or two.
The functionality you are interested in is pretty basic and hasn't changed too much. I'd bet a lot of the (reasonably simple) solutions you have already found would probably still work, maybe with a little bit of tweaking.
For pretty much any basic service endpoint, you would probably create a controller (not AppController - that is application-wide, hence you can't invoke it directly) method, considering Cake routes the controller/action into your url:
Cake consuming services from a different app would look like this:
http://cakeproject/collect/getInfo
class CollectController extends AppController {
public function getInfo($array = null) {
App::uses('HttpSocket', 'Network/Http');
$http = new HttpSocket();
$http->get('http://jmvcproject/controller/action', $array);
// ...etc.
}
Cake providing services from the same controller / action to a different app would simply be:
public function getInfo($array = null) {
$results = $this->Collect->find('all', $array);
// ...fetch the results
}
Or you could just loop over that array with foreach($this->data as $data) { ... to drop the class name. But if your data will include associated models, etc, Set is probably the most versatile and resilient solution.
Anyway, HTH
I created a Django app that had its own internal voting system and a model called Vote to track it. I want to refactor the voting system into its own app so I can reuse it. However, the original app is in production and I need to create a data migration that will take all the Votes and transplant them into the separate app.
How can I get two apps to participate in a migration so that I have access to both their models? Unfortunately, the original and separate apps both have a model named Vote now, so I need to be aware of any conflicts.
Have you tried db.rename_table?
I would start by creating a migration in either the new or old app that looks something like this.
class Migration:
def forwards(self, orm):
db.rename_table('old_vote', 'new_vote')
def backwards(self, orm):
db.rename_table('new_vote', 'old_vote')
If that does not work you can migrate each item in a loop with something along these lines:
def forwards(self, orm):
for old in orm['old.vote'].objects.all():
# create a new.Vote with old's data
models = {
'old.vote' = { ... },
'new.vote' = { ... },
}
Note: You must use orm[...] to access any models outside the app currently being migrated. Otherwise, standard orm.Vote.objects.all() notation works.