Sonata Admin : Add more groups to the service pool's list - sonata-admin

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" }

Related

Can't make work child admin in sonata admin bundle

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']]

Structuring user data by email address or by user ID

I want to have the users in the database structured in a way that makes it easier for a human to read and manage. Using the users email address as the property name instead of the User ID:
Users:
"Users" : {
"emailaddress#domain.com":{
"id": "DK66qu2dfUHt4ASfy36sdfYHS9fh",
"name": "A Display Name",
"groups": {
"moderators": true,
"users": true
}
},
{...}
}
So that if I have a list of users in a group, they can be read as a list of emails and not a list of user IDs.
Groups Such as:
"Groups": {
"moderators":{
"name": "moderator",
"members": {
"emailaddress#domain.com": true,
"emailaddress2#domain.com": true
}
}
}
Groups Instead of:
"Groups": {
"moderators":{
"name": "moderator",
"members": {
"DK66qu2dfUHt4ASfy36sdfYHS9fh": true,
"K2fkHYQDFOge3Hw7SjRaGP3N2sdo": true
}
}
}
However, using rules to verify a property of the user (such as their group), would require me to maintain two list of users, one like the list above, and another essentially a table of key-value pairs of ID's and email addresses so I can get the users email address from their uid.
Pseudo-code rule: Users[UsersKeyVal[auth.uid]].groups.moderator == true
With firebase, what would be considered the most acceptable practice? What are the pros and cons of both?
Please do not store user data under their email address! This will be BIG TROUBLE later.
Your users node should follow the 'standard' Firebase design pattern
users
uid_0
name:
gender:
etc
uid_1
name:
gender:
etc
The bottom line is that in general, it's best to disassociate the dynamic data stored in the node from the key of the node.
Why?
Suppose you build a complex structure with all kinds of links and references to frank#mycoolcompany.com and then #mycoolcompany.com gets acquired by #mynotsocoolcompany.com. Well, you will then have to go in and rebuild every reference to franks's email in the entire database. ugh.
Then what if there are 100 or 1000 users #mycoolcompany.com! Ouch.
If you disassociate the data, like my per above suggested structure, you just change the email address within the node and everything else... just works!
PLEASE, read this answer on stack overflow - written by a Firebaser and addresses your question
Firebase data structure and url
In my opinion there is no problem with your data structure.
According to the Doc
This is a necessary redundancy for two-way relationships. It allows you to quickly and efficiently fetch your members memberships
Also using the generated UId from firebase or your custom Id (here your e-mail) doesn't change the way firebase works. You just have to make sure your e-mail are unique.

Sequelize.js many to many eager loading

I have 2 models: User and Team
There are multiple kinds of users (in this case Mentors and Moderators) which are differentiated using an attribute in the User model(). The associations between User and Team are as below:
User.hasMany(models.Team, {as: 'Mentors', through: models.TeamMentor, foreignKey: 'mentorId'});
User.hasMany(models.Team, {as: 'Moderators', through: models.TeamModerator, foreignKey: 'moderatorId'});
Team.hasMany(models.User, {through: models.TeamMentor, foreignKey: 'teamId'});
Team.hasMany(models.User, {through: models.TeamModerator, foreignKey: 'teamId'});
Now I am trying to get the details of the team along with separate objects for all the mentors and moderators that are assigned to the teams. I came to know about the getters and setters for many to many relationships from the documentation but I am not sure how to use the method since there are two different kinds of associations between two models here:
Team - Mentor (User)
Team - Moderator (User)
How to correctly query for a team's details in this case?
PS: TeamMentor and TeamModerator are empty models to help the many to many joins
I'm assuming you have N:M relationships between all those models? Like this:
User ---mentors many---> Teams
User --moderates many--> Teams
Team --is moderated by many--> Users
Team --is mentored by many---> Users
If so, you might want to use the as option not only in the User.hasMany(Team) that you already have, but also in the Team.hasMany(User):
Team.hasMany(models.User, {as: 'mentors', through: models.TeamMentor, foreignKey: 'teamId'});
Team.hasMany(models.User, {as: 'moderators', through: models.TeamModerator, foreignKey: 'teamId'});
I think you can then eager load some or all of them during a query like so:
Team.findAll({
where: {...},
include: [
{model: User, as: `moderators` },
{model: User, as: `mentors` }
// or just use this to include everything:
// include: [{all:true}]
]
}).then(function(teams) {
console.log(JSON.stringify(teams));
// oneTeam.moderators: [array of User]
// oneTeam.mentors: [array of User]
});
(side note: I think your User objects currently have a 'getMentors()' method, and a 'mentors' property, that is an array of Team. Same for the 'moderators' property. Perhaps renaming that to 'mentoredTeams' and 'moderatedTeams' would make it clearer?)

Possible to filter user stories on name starts with?

Is it possible to filter user stories on their name? For example:
filters: [{properrty: 'Name', operator: 'startsWith', value: 'EPIC'}]
I am using the 2.0p5 rally sdk.
Also is there a documentation where I can look at for the App sdk? That explains querying on different attributes?
There isn't a startsWith operator, but you can use contains:
filters: [{property: 'Name', operator: 'contains', value: 'EPIC'}]
All possible values for filter operators can be found here:
https://help.rallydev.com/apps/2.0p5/doc/#!/api/Rally.data.QueryFilter-cfg-operator
You can then use the filterBy method to further narrow down the result set once the store has been loaded from the server:
store.filterBy(function(record) {
return record.get('Name').indexOf('EPIC') === 0;
});
The full App SDK documentation (including guides and links to the WSAPI documentation) can be found here:
https://help.rallydev.com/apps/2.0p5/doc/
I would also recommend upgrading to the most recent version of the SDK for app development (2.0rc2 as of this writing).
https://help.rallydev.com/apps/2.0rc2/doc/

MongoDB: Query and retrieve objects inside embedded array?

Let's say I have the following document schema in a collection called 'users':
{
name: 'John',
items: [ {}, {}, {}, ... ]
}
The 'items' array contains objects in the following format:
{
item_id: "1234",
name: "some item"
}
Each user can have multiple items embedded in the 'items' array.
Now, I want to be able to fetch an item by an item_id for a given user.
For example, I want to get the item with id "1234" that belong to the user with name "John".
Can I do this with mongoDB? I'd like to utilize its powerful array indexing, but I'm not sure if you can run queries on embedded arrays and return objects from the array instead of the document that contains it.
I know I can fetch users that have a certain item using {users.items.item_id: "1234"}. But I want to fetch the actual item from the array, not the user.
Alternatively, is there maybe a better way to organize this data so that I can easily get what I want? I'm still fairly new to mongodb.
Thanks for any help or advice you can provide.
The question is old, but the response has changed since the time. With MongoDB >= 2.2, you can do :
db.users.find( { name: "John"}, { items: { $elemMatch: { item_id: "1234" } } })
You will have :
{
name: "John",
items:
[
{
item_id: "1234",
name: "some item"
}
]
}
See Documentation of $elemMatch
There are a couple of things to note about this:
1) I find that the hardest thing for folks learning MongoDB is UN-learning the relational thinking that they're used to. Your data model looks to be the right one.
2) Normally, what you do with MongoDB is return the entire document into the client program, and then search for the portion of the document that you want on the client side using your client programming language.
In your example, you'd fetch the entire 'user' document and then iterate through the 'items[]' array on the client side.
3) If you want to return just the 'items[]' array, you can do so by using the 'Field Selection' syntax. See http://www.mongodb.org/display/DOCS/Querying#Querying-FieldSelection for details. Unfortunately, it will return the entire 'items[]' array, and not just one element of the array.
4) There is an existing Jira ticket to add this functionality: it is https://jira.mongodb.org/browse/SERVER-828 SERVER-828. It looks like it's been added to the latest 2.1 (development) branch: that means it will be available for production use when release 2.2 ships.
If this is an embedded array, then you can't retrieve its elements directly. The retrieved document will have form of a user (root document), although not all fields may be filled (depending on your query).
If you want to retrieve just that element, then you have to store it as a separate document in a separate collection. It will have one additional field, user_id (can be part of _id). Then it's trivial to do what you want.
A sample document might look like this:
{
_id: {user_id: ObjectId, item_id: "1234"},
name: "some item"
}
Note that this structure ensures uniqueness of item_id per user (I'm not sure you want this or not).

Resources