Doctrine 2 integration into ZF seems to make simple things very hard and time consuming(At least for me).
I cant just give a submitted form array to doctrine to automatically map key/value pairs to doctrine entities and it gets very complicated if i have a many-to-many entity and submitted form has nested array.
In symfony, submitted form keys/values are easily and AUTOMATICALLY mapped and saved to doctrine tables. I don't know how to do that in ZF especially if I have "Many to Many" and/or "Many to One" doctrine entities and I have **nested form elements which need multi-level iteration.
I don't want to Set every entity explicitly and create every entity object manually**.
Pain would be alot less if i used ZF`s native database architecture.
I have done some coding and now its done half-automatically but is not very useful.
I think the best solution is to use PHP's Reflection API to inject/retrieve values from your entities (using smart get/set detection as well). I started a little library called ObjectSerializer to help with the process but never finished. That said, if you look at the logic contained in these two classes you might get a good idea where to start.
You should program this sort of logic into your models.
I usually add this sort of logic into my form, for example
class Application_Form_SomeModel extends Zend_Form
{
// the usual stuff
public function populateModel(\Entity\Model $model)
{
$model->setSomething($this->getValue('something'));
$subForm = $this->getSubForm('name');
$relatedModel = new \Entity\RelatedModel;
$relatedModel->setSomething($subForm->getValue('something'));
$model->getRelatedModels()->add($relatedModel);
// assuming the related model collection has cascade persist
// otherwise you'll need to pass in the entity manager to persist
// the new model
}
}
I do it this way due to the fact the form's elements are really only known to the form. This allows you to encapsulate everything to do with the form and its element names within the form without having to assume anything else knows this information.
Related
I have a problem that's probably easy to fix, but I don't find the right way to do it.
I have the following situation:
I am building a web application where I use several forms. One of the forms uses and displays two Entity Framework models that have a 1:1 relation. It's one entity for all BaseData (common Data) and one entity for AdditionalData (specific Data). The form's Model is of type AdditionalData, which has a NavigationProperty of type BaseData.
When I want to save this "form" i.e. the two entities - what is the best way to do that?
Do I call two Actions seperately, like "Save(BaseData) then Save(AdditionalData)"(how?)?
Do I redirect from one Save Action to the Other one (also how?)?
Do I need to build a new Model to accomplish what I need (maybe with a special ModelBinder) or do I only need a special ModelBinder?
Can I manually invoke the ModelBinder for the "BaseData" manually from the Save Action of the AddidionalDataController?
Am I doing it completely wrong in the first place?
Thank you for any help!
I am developing a SPA using Angular-Breeze-WebAPI-EntityFramework.
Now Breeze uses the Entity Framework metadata information to create it's own Breeze models. We use this in our application for Breeze validation.
So far, it's all been nice and easy. Now we are having to create a search page (say for querying customers). The search can be by Customer.Name or by Product.Id (which would return a list of customers who have bought that product). The result is a ng-repeater, which displays Customer.Name, Order.LastPlaced etc.
if you are getting confused by the tables and columns, forget that. What I am only trying to get to is that, both the search object and the result object are not 1:1 with Entity tables (or objects). So obviously I feel the need to create a custom object (one for the search and one for the results). My question primarily is where and how do I create that object?
If I create it at the data layer, Breeze would have no idea of the metadata for each of the properties (since it uses EF for that).
I obviously can't create just a JavaScript object, since I will have to query the database (using EF) to search and populate the object.
So where does one create such a custom object (traversing multiple tables) such that Breeze still can figure out the metadata and perform validation and such when the need arises?
Thank you all.
You can create metadata on the client for types that the server either doesn't know about or doesn't have the schema for. See http://www.breezejs.com/documentation/metadata-by-hand.
I going to set up some large forms with up to 100 fields.
Now my question is if there is some best practise about handling such forms.
Especially:
Entity relations
Form object it self
Does somebody have experience about such tasks?
Should I put all together in one entity, one form, structured with jQuery in subforms or should I group the attributes to arrays as much as possible?
Regards,
Bodo
Whereas official documentation show many examples of forms directly linked to entities, I think this is not the best approach. In rare case it's good, when your form has exactly the same fields as your entity.
Your form must represent what you get in the browser, so only html inputs/textearea/select. I usually create a formData class, like an entity, that holds validation constraints and has the same structure as the form.
You have to initialize this formData object with your persisted datas before loading the form, and after submission, you update your entities with your formData object...
I am creating some complex forms that are built from multiple entities. I create a form class for each entity and then create a composite form class that holds the various combinations of forms I need (which is in someways similar to PéCé's suggestion).
If I don't need all of the fields, that is fine because I can control which fields are rendered in the twig template. If I need fields that aren't in the form class, I can add them to the template and process the form data as appropriate. For all of this effort I get some built in validation and flexibility to reuse forms from multiple entities and bundles.
I have an Entity called "Product", this entity, through table mapping, merges 6 tables that have a 1 to 1..0 relationship with "Products". This all works wonderfully. There is another property I want to add to "Products", which is sBBR_rate, this value is not in a table that has a direct 1 to 1..0 relationship, it is related through a link table as below:
When I import the two tables into the EDM, I can't see a way in the "Mapping Details" of
"Product" to reference the sBBR_rate. I can reference RatesLink and link that to the "Products" primary key, however, I cannot reference the BBR table.
The methods I can think of to work "around" this is are as follows:
Create a view, reference the view in the EDM.
Create an SP and use a function import to retrieve the BBR when it is required.
Create a "Rates" entity in the EDM that can then draw down the sBBR_rate into it. Navigate to the Products BBR through Product.Rates.sBBR_rate.
Is there a better way I can do this that doesn't feel so much like a fudge? Perhaps by directly editing the XML of the Mapping or Conceptual layers of the EDM?
Thanks for your input.
Because the multiplicities on the Product -> RatesLink and RatesLink -> BBR relationships are 0 to 1, you should be able to access the sBBR_rate from a Product instance like this:
myProductInstance.RatesLink.BBR.sBBR_rate
I can see on the EDM screenshot that RatesLink has a Product and BBR property, which would indicate this should be available - is it?
On a side note, if it makes sense for the sBBR_rate property to commonly be accessed directly from Product, you might want to follow the law of demeter and create a property on Product which returns it directly.
The model we are using is to extend entities by using partial classes which we've found useful so we can get additional properties in the autogenerated classes (we are using a POCO T4 template to autogen but I believe this would work just as well with the default entity object generation).
So we would have
//.. this one is from the T4 template
public partial class Product
{
//.. all the autogenerated methods
}
and in a separate file that isn't autogened
//.. now in a separate file created by me
public partial class Product
{
//.. my custom properties and methods to make the entities more usable
public string BBRRate
{
get {return this.RatesLink.BBR.sBBR_rate; }
}
}
This means that I can just do
myProduct.BBRRte
I know there are other ways to do this by amending the edmx file but this one we found easy to implement. You just need to watch performance because you are potentially loading extra data. Also we did this with LazyLoading turned on but with more work you wouldn't have to
We also experimented with hooking into the ObjectMaterialized event in the ObjectContext class to preload some of these properties. Using a custom interface i.e. IMaterialisable we could check if the object was of that type then call a method (Materialise) to prepopulate some of the properties. This seems like a good idea but we didn't widely use it - it was easy to load up too much stuff. If you do the load on the properties in the partial classes then it becomes more efficient. Just my experience.
Anyway - as always an interesting question and good luck again with your dev.
EDIT
There is a rule that everything in the store layer must be represented some way in your conceptual layer. Therefore removing the tables from the conceptual layer but bring through some of the properties I don't think will work in it's gross form. Therefore I can think of two further options
Create a View on the database and bring that in as you have already mentioned. TBH this is what I would do.
Use the DefiningQuery element directly in your xml (the store layer) and map the query through to a custom entity of your exact design. Julie Lerman describes this as the ultimate escape hatch for Entity Framework.
Remember though - if you manual amend the XML in point 2 then you lose the ability to automatically update the module through the IDE
I ended up creating a view and then linking this view in the EDM, this worked a treat.
I was wondering what the general recommendation is for Entity Framework in terms of data validation. I am relatively new to EF, but it appears there are two main approaches to data validation.
The first is to create a partial class for the model, and then perform data validations and update a collection of rule violations. This is outlined at http://msdn.microsoft.com/en-us/library/cc716747.aspx
The other is to use data annotations and then have the annotations perform data validation. Scott Guthrie explains this on his blog at http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx.
I was wondering what the benefits are of one over the other. It seems the data annotations would be the preferred mechanism, especially as you move to RIA Services, but I want to ensure I am not missing something. Of course, nothing precludes using both of them together.
Thanks
John
I have been using DataAnnotations using MVC 2 and it works great. I have not tried the partial on an entity object for validation, but I see its uses. Basically if I create a partial class on an entity object I use it to default data such as a GUID identifier. or Create Date or modified Date. I guess it would be useful to add validations in the partial class perhaps for some complex validation that needs to happen in the entity layer but even then those validations could be accomplished in custom validator. If you are using an MVC website then I would personally use dataannotations.