CakePHP - deep model binding vs uses - cakephp

I recently read an old article it which this was suggested
Avoid using the $uses array You’ve got two completely unrelated models, but you need info from one in the controller of another. The
first idea is to add them to the $uses array. Hey, it’s easy and gets
the job done. Well, to make the long story short, it’s bad practice.
Think about your model bindings and ensure that models are really not
related to one another. Sometimes your User model is definitely not
related to CommentRating, but you absolutely need it in your users
controller. Well, just by chance it appears that
User->Post->Comment->CommentRating. It’s a deep binding that may not
be obvious at first, but by employing such a chain of models you can
easily avoid using the $uses array, when it’s really not necessary.
For the sake of readability/maintainability, I tend to prefer putting CommentRating in the uses array and then calling $this->CommentRating directly.
Is using the $uses array really bad practice and if so why?

That quote cuts a long story a bit too short. Why is it a bad practice? He doesn't even give one reason. I wouldn't pay too much attention to it.
I'm no expert, but there are definitely cases when readability and common sense in your code is more important than a minute performance increase or whatever else avoiding $uses may provide. I'll be continuing to use $uses instead of obscure model chains like User->Post->Comment->Rating
EDIT: And as #tigrang added, with lazy loading of Models in Cake 2, there's not really a performance benefit anyway!

Related

APEX best practice

I am new to Salesforce apex coding. My first class that I am developing has 10 methods and is some 800 lines.
I haven’t added much of exception handling, so the size should swell further.
I am wondering, what the best practice for Apex code is... should I create 10 classes with 1 method instead of letting 1 class with 10 methods.
Any help on this would be greatly appreciated.
Thanks
Argee
What do you use for coding? Try to move away from Developer Console. VSCode has some decent plugins like Prettier or Apex PMD that should help you with formatting and making methods too complex. ~80 lines/method is so-so. I'd worry about passing long lists of parameters and having deeply nested code in functions rather than just their length.
There are general guidelines (from other languages, there's nothing special about Apex!) that ideally function should fit on 1 screen so programmer can see it whole without scrolling. Read this one, maybe it'll resonate with you: https://dzone.com/articles/rule-30-%E2%80%93-when-method-class-or
I wouldn't split it into separate files just for sake of it, unless you can clearly define some "separation of concerns". Say 1 trigger per object, 1 trigger handler class (ideally derived from base class). Chunkier bits not in the handler but maybe in some "service" style class that has public static methods and can operate whether called from trigger, visualforce, lightning web component, maybe some one-off data fix would need these, maybe in future you'd need to expose part of it as REST service. And separate file for unit tests (as blasphemous as it sounds - try to not write too many comments. As you're learning you'll need comments to remind yourself what built-in methods do but naming your functions right can help a lot. And a well-written unit test is better at demonstrating the idea behind the code, sample usage and expected errors than comments that can be often overlooked).
Exception handling is an art. Sometimes it's good to just let it throw an exception. If you have a method that creates Account, Contact and Opportunity and say Opportunity fails on validation rule - what should happen? Only you will know what's good. Exception will mean the whole thing gets rolled back (no "widow" Accounts) which sucks but it's probably "more stable" state for your application. If you naively try-catch it without Database.rollback() - how will you tell user to not create duplicates with 2nd click. So maybe you don't need too much error handling ;)

When not to use Containable Behavior in CakePhp 2.x

After a few times adding Containable Behavior to my various model classes, I have a good mind to simply chuck the line into AppModel instead and thus make every model Containable. Which then makes me wonder, is there any situation where it is not desirable or counterproductive for a particular model to have Containable Behavior?
I would say too few to be worried about. I put containable in App Model:
class AppModel extends Model {
public $recursive = -1;
public $actsAs = array('Containable');
}
Containable overrides recursive anyway, so you don't really need to set recursive to -1, but I do just for clarity. Always using containable forces you into the best practice of always using only what you want/need. For small apps, it's not the end of the world to just use recursive and ignore containable, but it's still not best practice.
So, I guess the only argument for using recursive instead of containable would be that in small apps, you save yourself a tiny amount development time, and it won't really noticeably affect performance. I'd definitely go with using containable by default, and removing it where you deem it overkill, rather than the other way around.
Containable can be dangerous b/c Cake acts in an extremely inefficient manner in order to get the nested results.
This site explains it well...
http://www.endyourif.com/cakephp-containable-statement-pitfalls/
Basically though the nice array you are getting back is the results of many different queries while your best performance may come from using a single query with joins.
The convenience of containable is undeniable though.

C, design: removing global objects

I'm creating a small Avida-style life simulation. I started out with a very basic, everything-is-global 600-line program in a single file to test some ideas, and now I want to create a real design.
Among other things, I had a global configuration object that every other function got something out of. Now, I must localize the object and pass pointers around. Thing is, mostly everyone needs this object. I've thought of three possible solutions:
a) Keep the configuration object
global (simplest, though not really a
solution)
b) Store pointers everywhere they are
needed (easy enough, though a waste
of memory, since some small
plain-old-data structures would need
it).
c) Create factories for the POD types
that need access to options, and have
the factory perform all operations on
them.
Of my ideas, only (c) sounds logical, but I don't want to needlessly complicate the structure. What would you guys do?
I'm fine with new ideas, and will provide whatever information about the program you want to know.
Thanks in advance!
I have to agree with #Carl Norum: there is nothing wrong with the global config setup you have now. You say that everybody "got something out of" it. As you know, the problem with globals comes when everybody writes into them. In your case, the config info truly is needed globally so deserves to be global.
If you want to make it be a little more decoupled and protected -- a little less global-ish -- then why not add some read/write access routines.
See, storing pointers everywhere isn't going to really solve the problem: it will only add a layer of indirection that will merely disguise or camouflage what are, in reality, the global accesses that are making you nervous. And that extra layer of indirection will add juuuuust enough room for juuuuust a teeny-weeny little bug to creep in.
So, bottom line: if stuff is naturally global then make it global and don't worry about the usual widespread received wisdom that's mostly correct but might not be the right thing in your application. To always be bound by the rules/propaganda that CS teachers put out there is, imo, the perfect example of a foolish consistency.
Global variables are awesome. Spend your time actually getting something done instead of refactoring for no reason. Every company I have worked at uses them heavily.
Ask yourself if you're actually gaining anything by moving it to an object you're just passing around everywhere. Might as well save yourself the extra complexity..
Go for B, unless profiling proves it to be a problem. On most machines, the memory required to store a pointer is very, very trivial.

Silverlight LINQtoSQL: one big dataclass, or several small ones?

I'm new to Silverlight, but being dumped right into the fray - good way to learn I suppose :o)
Anyway, the webapp I'm working on has a relatively complex database structure that represents various object types that are linked to each other, and I was wondering 2 things:
1- What is the recommended approach when it comes to dataclasses? Have just one big dataclass, or try and separate it into several smaller dataclasses, keeping in mind they will need to reference each other?
2- If the recommended approach is to have several dataclasses, how do you define the inter-dataclasses references?
I'm asking because I did a small test. In my DB (simplified here, real model is more complex but that's not important), I have a table "Orders" and a table "Parameters". "Orders" has a foreign key on "Parameters". What I did is create 2 dataclasses.
The first one, ParamClass, were I dropped the "Parameters" table only, so I can have a nice "parameter" class. I then created a simple service to add basic SELECT and INSERT functionality.
The second one, OrdersClass, where I dropped both tables, so that the relation between the tables would automatically create a "EntityRef<parameter>" variable inside the "order" class. I then removed the "parameters" class that was automatically created in the OrdersClass dataclass, since the class has already been declared in the ParamClass dataclass. Again I created a small service to test it.
So far so good, it builds happily. The problem is that when I try to handle things on the application code, I added service references for both dataclasses, but it is not happy doing something like:
OrdersServiceReference.order myOrder = new OrdersServiceReference.order();
myOrder.parameter = new ParamServiceReference.parameter(); //<-PROBLEM IS HERE
It comlpains that it cannot implicitly convert from type 'MytestDC.ParamServiceReference.parameter' to 'MytestDC.OrdersServiceReference.parameter'
Do I somehow need to declare some sort of reference to ParamClass from OrdersClass, or how do I "convert" one to the other?
Is this even a recommended and efficient way of doing this?
Since it's a team-project, I initially wanted to separate the dataclasses so that they (and their services) can be easily checked out by one member without checking out the whole entire dataclass.
Any help appreciated!
PS: using Silverlight 4, in case that's important
Based on the widely accepted Single Responsability Principle (SRP), a class should always be responsible for one task, and one task only.
That pretty much invalidates your "one big dataclass" approach.
I would always recommend smaller, more manageable bits that can be combined, instead of one humonguous class that does everything (except brew coffee for you).
Resources for the SRP:
Wikipedia on SRP
OODesign: Single Responsibility Principle
ObjectMentor: list of articles on good app design - which has a few links to PDF documents, like this one on SRP written by Robert C. Martin - the "guru" on proper OO design
OK, some more research let me to this: it is not simple to separate classes from a relational model using LINQtoSQL. I ended up switching to an Entity Framework approach, which itself doesn't deal with it gracefully (see here and there, for example), but at least it solved another major problem I had with LINQtoSQL.
There are other ORMs out there that are apparently much more capable at this (NHibernate comes up often in recommendations), unfortunately, I don't have time to investigate them now, being under such a tight deadline.
As for the referencing, it was quite simple, change the line to:
myOrder.parameter = new OrderServiceReference.parameter();
even though I removed the declaration from that dataclass.
Hope this helps someone!

Why am I getting an undefined property error when my relationships seem correct?

I'm having a slight problem that I can't figure out, but should be really simple.
I have the following model structure in my cakePHP (1.3) app:
ProspectiveQuote [hasMany] QuoteUnit [belongsTo] Unit
but in my ProspectiveQuotesController the line:
$this->ProspectiveQuote->QuoteUnit->Unit->find('list');
gives me the following error:
Undefined property: AppModel::$Unit
Of course, it shouldn't be looking at AppModel, it should be looking at QuoteUnit.
If I do $this->ProspectiveQuote->QuoteUnit->find('all') it seems to get results (allbeit without any related model data...) so it obviously finds the QuoteUnit well enough, and I have double-checked its relationship with Unit, and it all seems fine...
Seems like a simple enough problem. From what I can see people with this problem usually have their model names wrong (or plural) but this is not the case here...
What could I be doing wrong?
I would say to double check over the syntax of your model associations to make sure they are correct. Or back them up, and bake out some new models to test with, just to ensure that it's how you expect it.
Another great thing is to grab the DebugKit http://www.ohloh.net/p/cakephp-debugkit Which will help you to see your variables and your sql queries.
As mentioned in Leo's comment I would try and avoid uses() as it puts, or did put in 1.2 a bit of a big overhead onto your stack.
Have you set var $uses = array('ProspectiveQuote','QuoteUnit','Unit'); in your controller? (although there are slightly more efficient ways of doing this) - see http://book.cakephp.org/2.0/en/controllers.html#controller-attributes
If you do this you can access your associated models like:
$this->Unit->find('list');
or
$this->ProspectiveQuote->QuoteUnit->Unit->find('list');
I know which I prefer.

Resources