cfWheels - creating an object related objects - coldfusion

I have a new model myModel that I'm creating with a one-to-many relationship to a bunch of sub-models mySubModel that are being created at the same time.
when I try to save the model:
<cfset myModel=model("myModel").new(params.mymodel)>
<cfset myModel.save()>
only the model part gets saved, the items inside params.myModel.mySubModels do not get created. The models have their relations setup and I can get it to pull the data in the same format out of myModel with the right include.
I could save each of the models separately, but I'm worried about that causing problems or just creating needles lines of code if cfwheels is able to handle this already. I would have to save the initial model and then save the additional sub-models, and if there is an error, delete the model and other sub-models that have already been written to the database.

As long as the main object relates to sub-objects with hasMany, Nested Properties will be invaluable to you.
In the main model:
function init() {
hasMany("subModels");
nestedProperties("subModels");
}
Then a call to save() in the controller runs saves on the parent object and all of its associated children.
function create() {
myModel = model("myModel").new(params.myModel);
// This call to `save()` saves associated children represented in `params.myModel` too
if (myModel.save()) {
redirectTo(route="myRoute", success="The model was saved successfully.");
}
else {
flashInsert(error="There was an error saving the model.");
renderPage(action="new");
}
}
If you can comment more about your particular data structure, I can help you with the form part. Calling something "subModel" is only going to get us so far in this discussion.

I'm looking at the docs here: http://cfwheels.org/docs/1-1/chapter/associations specifically, the section related to "hasMany()". I see several functions there for creating new child records based on the parent record, but none that will create multiple at a single go. At best, it seems like this is what you could do:
<cfset myModel=model("myModel").create(params.mymodel)>
<cfloop array="#params.mymodel.mySubModels#" index="thisSubModel">
<cfset myModel.createMySubModel(thisSubModel)>
</cfloop>
Which really doesn't seem that bad.

I would define two methods in the model's init, like this:
validate(methods="validateChildren");
afterCreate(methods="createChildren");
validateChildren would run validation for each child model (defined in corresponding models, of course), consider using valid for this purpose -- it fires the validation without saving data.
Use syntax like this to pass the error to the parent model level:
addError(property="someproperty", message="Something wrong happened");
Then if there are not errors createChildren method would create all needed sub-models, using params to override the safe defaults. Personally I would not use looping over params because relying on external data is not so good idea and can mess the stuff.

Related

Prestashop admin orders controller

I would like to ask about this controller.
In past versions like 1.5 I could find it in admin/tabs and add additional functions.
In 1.6 version I can`t find any admin classes files. So I should edit controllers/admin/AdminOrdersController yes?
elseif(isset($_POST['submitInvoice'])){
if ($this->tabAccess['edit'] === '1')
{
mysql_query('UPDATE `'._DB_REFIX_.'orders` SET `invoice_number` = \''.$_POST['invoice_number'].'\',`order_date` = \''.$_POST['order_date'].'\', `changed_invoice`=1, `manager`=\''.$cookie->firstname.' '.$cookie->lastname.'\', `changedStatus`= \''.$_POST['changedStatus'].'\' WHERE `id_order` = '.$_GET['id_order']);
}
}
I add this code to update some values like invoice number or order date. But I can`t to update this. Got same date and number. Is it bad method to update or what?
You should always use modules and hooks to modify PrestaShop logic if possible
If you need to override a function and there is nor suitable hook, you should use overrides: override/controllers/admin/AdminOrderController.php. Contents of this files should look like : AdminOrderController extends AdminOrderControllerCore. If you're unsure what I mean, you should try searching for any override classes in overide folder.
You code is extremely unsafe. You should at least use Db::getInstance()->execute($sql);.
You code might not be working because you are writing you values somewhere in the middle of a function, and the Order is an object, which mean that possibly the Order object is saved after you wrote you values to database. When the order object is saved, it overwrites your values

Serializing unloaded relationships

I've written my owner adapter and serializer for my Ember.js application. I follow the JSON API standard (the ID format), so most of my JSON looks something like this:
{
"id": "2364",
"name": "Test",
"links": {
"single": "2834",
"multiple": ["2292", "9584", "8475"]
}
}
However, all of my relationships are loaded lazily (I defined the async attribute as true). This is required, because some of the records can become quite large. The problem is when I try to serialize the model. If the relationship isn't loaded yet, I won't get the ID for the related model. So let's say I edit the name of the model above and try to save it. I'll get this JSON:
{
"id": "2364",
"name": "This has been edited",
"links": {
"single": null,
"multiple": []
}
}
Because the relationships aren't loaded yet, it gives me empty values. However, because the relationships haven't been edited, they should be exactly the same as when they came in. To get that data back, I can use model.get('data') and get an object that contains the IDs that were originally returned from the server. So if I know a relationship is unloaded, I can call model.get('data.relationshipName') and get those original IDs back.
Now the real problem: if the relationship is loaded fully, I want to serialize it as it exists, in case it was edited. However, if it is not loaded fully, I don't want to attempt to load it. In that case, I can just get the IDs from the data property. So, how can I determine if a relationship is loaded or not, without loading it?
As usual, I did quite a bit of legwork and trickery, but I figured it out. Here's what you do:
Have all of your models inherit from a single base class. In that base class, you want to do three things. First, in the init method, created a hash (object) on the instance (leave it empty). Next, override the get method, and if the user tries to access one of the relationships, update the hash you created to reflect that. Finally add a method like wasRelationshipAccessed(name) to the class to read from the hash. This will tell you exactly which relationships where accessed, and by process of elimination, which ones weren't.
Also in that base class, have the init method create another hash. This one is going to store the original values of the relationships from the server. I called mine originalLinks.
Override DS.Store and assign it to App.Store. In that class, override the push method. In the override, call this._super.apply(this, arguments) and save the return value. That return value is the record. Now that you have both the data from the server and the record, insert the relationships from the server into the originalLinks hash you made above.
Finally, in your serializer, use your wasRelationshipAccessed function. If the relationship was accessed, it was loaded. If it wasn't accessed, get the data from the originalLinks hash.
And that's all there is to it. If you're going to do this, I highly suggest writing unit tests for your serializer, adapter and that part of the store. That will ensure that you'll catch any changes to the internals of Ember-Data.

Yii dynamic model id

So I'm working on some unit tests and relational fixtures.
I'm creating a model dynamically like:
$model = CActiveRecord::model('Post');
$post = $model->findByPk(1);
But after that I cannot for some reason get $post->id. I traced the problem to CActiveRecord class:
public function __get($name)
{
if(isset($this->_attributes[$name]))
return $this->_attributes[$name];
...
Where $name = "id". It says that $this->_attributes[$name] does not exist! As a matter of fact _attributes is empty.
My Post class does not define id (or any other properties) as a public property and I don't want to do so either. I just let the AR map it to table columns for me.
What am I missing?
Edit 1
My fixtures are regular Yii fixtures - nothing really special about them.
What differs is the way I load them really. I extended the CDbFixtureManager to be able to specify the order in which they should be loaded by overloading load() method. Only thing of interest that actually fails is that in the fixtures that have foreign keys I use the following:
'comment1' => array('post_id' => $this->getRecord('Post', 'post1')->id);
That's where it fails. getRecord returns the actual Post record (since I know the Post fixture has already been successfully loaded and exists in DB), but on the ->id part I get an exception about that attribute not existing.
If I go into Post model and add public $id; to it, then everything works! But I'm not sure if it's good practice to go about declaring all properties public like that.
If you look at this page carefully:
http://www.yiiframework.com/doc/guide/1.1/en/test.unit
you'll see that they use an array form for retrieving fixtures:
$this->posts['sample1']['id']
There is an alias defined in their fixture array for each record and fixture items aren't loaded as models really ...
Does that help? If not, it would be helpful to see your fixture file :-)
I think I found the root cause of this issue for me. While my FixtureManager was using the testdb DBConnection, the models still used the regular one.
For whatever reason, my debugger was giving me misleading errors like the one described in my original post.
Once I was able to set the DBConnection of all Models in the unit test the puzzle snapped into place and everything is now working smoothly!

Django - How to pass dynamic models between pages

I have made a django app that creates models and database tables on the fly. This is, as far as I can tell, the only viable way of doing what I need. The problem arises of how to pass a dynamically created model between pages.
I can think of a few ways of doing such but they all sound horrible. The methods I can think of are:
Use global variables within views.py. This seems like a horrible hack and likely to cause conflicts if there are multiple simultaneous users.
Pass a reference in the URL and use some eval hackery to try and refind the model. This is probably stupid as the model could potentially be garbage collected en route.
Use a place-holder app. This seems like a bad idea due to conflicts between multiple users.
Having an invisible form that posts the model when a link is clicked. Again very hacky.
Is there a good way of doing this, and if not, is one of these methods more viable than the others?
P.S. In case it helps my app receives data (as a json string) from a pre-existing database, and then caches it locally (i.e. on the webserver) creating an appropriate model and table on the fly. The idea is then to present this data and do various filtering and drill downs on it with-out placing undue strain on the main database (as each query returns a few hundred results out of a database of hundreds of millions of data points.) W.R.T. 3, the tables are named based on a hash of the query and time stamp, however a place-holder app would have a predetermined name.
Thanks,
jhoyla
EDITED TO ADD: Thanks guys, I have now solved this problem. I ended up using both answers together to give a complete answer. As I can only accept one I am going to accept the contenttypes one, sadly I don't have the reputation to give upvotes yet, however if/when I ever do I will endeavor to return and upvote appropriately.
The solution in it's totality,
from django.contrib.contenttypes.models import ContentType
view_a(request):
model = create_model(...)
request.session['model'] = ContentType.objects.get_for_model(model)
...
view_b(request):
ctmodel = request.session.get('model', None)
if not ctmodel:
return Http404
model = ctmodel.model_class()
...
My first thought would be to use content types and to pass the type/model information via the url.
You could also use Django's sessions framework, e.g.
def view_a(request):
your_model = request.session.get('your_model', None)
if type(your_model) == YourModel
your_model.name = 'something_else'
request.session['your_model'] = your_model
...
def view_b(request):
your_model = request.session.get('your_model', None)
...
You can store almost anything in the session dictionary, and managing it is also easy:
del request.session['your_model']

Move a python / django object from a parent model to a child (subclass)

I am subclassing an existing model. I want many of the members of the parent class to now, instead, be members of the child class.
For example, I have a model Swallow. Now, I am making EuropeanSwallow(Swallow) and AfricanSwallow(Swallow). I want to take some but not all Swallow objects make them either EuropeanSwallow or AfricanSwallow, depending on whether they are migratory.
How can I move them?
It's a bit of a hack, but this works:
swallow = Swallow.objects.get(id=1)
swallow.__class__ = AfricanSwallow
# set any required AfricanSwallow fields here
swallow.save()
I know this is much later, but I needed to do something similar and couldn't find much. I found the answer buried in some source code here, but also wrote an example class-method that would suffice.
class AfricanSwallow(Swallow):
#classmethod
def save_child_from_parent(cls, swallow, new_attrs):
"""
Inputs:
- swallow: instance of Swallow we want to create into AfricanSwallow
- new_attrs: dictionary of new attributes for AfricanSwallow
Adapted from:
https://github.com/lsaffre/lino/blob/master/lino/utils/mti.py
"""
parent_link_field = AfricanSwallow._meta.parents.get(swallow.__class__, None)
new_attrs[parent_link_field.name] = swallow
for field in swallow._meta.fields:
new_attrs[field.name] = getattr(swallow, field.name)
s = AfricanSwallow(**new_attrs)
s.save()
return s
I couldn't figure out how to get my form validation to work with this method however; so it certainly could be improved more; probably means a database refactoring might be the best long-term solution...
Depends on what kind of model inheritance you'll use. See
http://docs.djangoproject.com/en/dev/topics/db/models/#model-inheritance
for the three classic kinds. Since it sounds like you want Swallow objects that rules out Abstract Base Class.
If you want to store different information in the db for Swallow vs AfricanSwallow vs EuropeanSwallow, then you'll want to use MTI. The biggest problem with MTI as the official django model recommends is that polymorphism doesn't work properly. That is, if you fetch a Swallow object from the DB which is actually an AfricanSwallow object, you won't get an instance o AfricanSwallow. (See this question.) Something like django-model-utils InheritanceManager can help overcome that.
If you have actual data you need to preserve through this change, use South migrations. Make two migrations -- first one that changes the schema and another that copies the appropriate objects' data into subclasses.
I suggest using django-model-utils's InheritanceCastModel. This is one implementation I like. You can find many more in djangosnippets and some blogs, but after going trough them all I chose this one. Hope it helps.
Another (outdated) approach: If you don't mind keeping parent's id you can just create brand new child instances from parent's attrs. This is what I did:
ids = [s.pk for s in Swallow.objects.all()]
# I get ids list to avoid memory leak with long lists
for i in ids:
p = Swallow.objects.get(pk=i)
c = AfricanSwallow(att1=p.att1, att2=p.att2.....)
p.delete()
c.save()
Once this runs, a new AfricanSwallow instance will be created replacing each initial Swallow instance
Maybe this will help someone :)